1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /******************************************************************************* |
3 | * |
4 | * CTU CAN FD IP Core |
5 | * |
6 | * Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU |
7 | * Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded |
8 | * Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU |
9 | * Copyright (C) 2018-2022 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded |
10 | * |
11 | * Project advisors: |
12 | * Jiri Novak <jnovak@fel.cvut.cz> |
13 | * Pavel Pisa <pisa@cmp.felk.cvut.cz> |
14 | * |
15 | * Department of Measurement (http://meas.fel.cvut.cz/) |
16 | * Faculty of Electrical Engineering (http://www.fel.cvut.cz) |
17 | * Czech Technical University (http://www.cvut.cz/) |
18 | ******************************************************************************/ |
19 | |
20 | #include <linux/clk.h> |
21 | #include <linux/errno.h> |
22 | #include <linux/ethtool.h> |
23 | #include <linux/init.h> |
24 | #include <linux/bitfield.h> |
25 | #include <linux/interrupt.h> |
26 | #include <linux/io.h> |
27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> |
29 | #include <linux/skbuff.h> |
30 | #include <linux/string.h> |
31 | #include <linux/types.h> |
32 | #include <linux/can/error.h> |
33 | #include <linux/pm_runtime.h> |
34 | |
35 | #include "ctucanfd.h" |
36 | #include "ctucanfd_kregs.h" |
37 | #include "ctucanfd_kframe.h" |
38 | |
39 | #ifdef DEBUG |
40 | #define ctucan_netdev_dbg(ndev, args...) \ |
41 | netdev_dbg(ndev, args) |
42 | #else |
43 | #define ctucan_netdev_dbg(...) do { } while (0) |
44 | #endif |
45 | |
46 | #define CTUCANFD_ID 0xCAFD |
47 | |
48 | /* TX buffer rotation: |
49 | * - when a buffer transitions to empty state, rotate order and priorities |
50 | * - if more buffers seem to transition at the same time, rotate by the number of buffers |
51 | * - it may be assumed that buffers transition to empty state in FIFO order (because we manage |
52 | * priorities that way) |
53 | * - at frame filling, do not rotate anything, just increment buffer modulo counter |
54 | */ |
55 | |
56 | #define CTUCANFD_FLAG_RX_FFW_BUFFERED 1 |
57 | |
58 | #define CTUCAN_STATE_TO_TEXT_ENTRY(st) \ |
59 | [st] = #st |
60 | |
61 | enum ctucan_txtb_status { |
62 | TXT_NOT_EXIST = 0x0, |
63 | TXT_RDY = 0x1, |
64 | TXT_TRAN = 0x2, |
65 | TXT_ABTP = 0x3, |
66 | TXT_TOK = 0x4, |
67 | TXT_ERR = 0x6, |
68 | TXT_ABT = 0x7, |
69 | TXT_ETY = 0x8, |
70 | }; |
71 | |
72 | enum ctucan_txtb_command { |
73 | TXT_CMD_SET_EMPTY = 0x01, |
74 | TXT_CMD_SET_READY = 0x02, |
75 | TXT_CMD_SET_ABORT = 0x04 |
76 | }; |
77 | |
78 | static const struct can_bittiming_const ctu_can_fd_bit_timing_max = { |
79 | .name = "ctu_can_fd" , |
80 | .tseg1_min = 2, |
81 | .tseg1_max = 190, |
82 | .tseg2_min = 1, |
83 | .tseg2_max = 63, |
84 | .sjw_max = 31, |
85 | .brp_min = 1, |
86 | .brp_max = 8, |
87 | .brp_inc = 1, |
88 | }; |
89 | |
90 | static const struct can_bittiming_const ctu_can_fd_bit_timing_data_max = { |
91 | .name = "ctu_can_fd" , |
92 | .tseg1_min = 2, |
93 | .tseg1_max = 94, |
94 | .tseg2_min = 1, |
95 | .tseg2_max = 31, |
96 | .sjw_max = 31, |
97 | .brp_min = 1, |
98 | .brp_max = 2, |
99 | .brp_inc = 1, |
100 | }; |
101 | |
102 | static const char * const ctucan_state_strings[CAN_STATE_MAX] = { |
103 | CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_ERROR_ACTIVE), |
104 | CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_ERROR_WARNING), |
105 | CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_ERROR_PASSIVE), |
106 | CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_BUS_OFF), |
107 | CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_STOPPED), |
108 | CTUCAN_STATE_TO_TEXT_ENTRY(CAN_STATE_SLEEPING) |
109 | }; |
110 | |
111 | static void ctucan_write32_le(struct ctucan_priv *priv, |
112 | enum ctu_can_fd_can_registers reg, u32 val) |
113 | { |
114 | iowrite32(val, priv->mem_base + reg); |
115 | } |
116 | |
117 | static void ctucan_write32_be(struct ctucan_priv *priv, |
118 | enum ctu_can_fd_can_registers reg, u32 val) |
119 | { |
120 | iowrite32be(val, priv->mem_base + reg); |
121 | } |
122 | |
123 | static u32 ctucan_read32_le(struct ctucan_priv *priv, |
124 | enum ctu_can_fd_can_registers reg) |
125 | { |
126 | return ioread32(priv->mem_base + reg); |
127 | } |
128 | |
129 | static u32 ctucan_read32_be(struct ctucan_priv *priv, |
130 | enum ctu_can_fd_can_registers reg) |
131 | { |
132 | return ioread32be(priv->mem_base + reg); |
133 | } |
134 | |
135 | static void ctucan_write32(struct ctucan_priv *priv, enum ctu_can_fd_can_registers reg, u32 val) |
136 | { |
137 | priv->write_reg(priv, reg, val); |
138 | } |
139 | |
140 | static u32 ctucan_read32(struct ctucan_priv *priv, enum ctu_can_fd_can_registers reg) |
141 | { |
142 | return priv->read_reg(priv, reg); |
143 | } |
144 | |
145 | static void ctucan_write_txt_buf(struct ctucan_priv *priv, enum ctu_can_fd_can_registers buf_base, |
146 | u32 offset, u32 val) |
147 | { |
148 | priv->write_reg(priv, buf_base + offset, val); |
149 | } |
150 | |
151 | #define CTU_CAN_FD_TXTNF(priv) (!!FIELD_GET(REG_STATUS_TXNF, ctucan_read32(priv, CTUCANFD_STATUS))) |
152 | #define CTU_CAN_FD_ENABLED(priv) (!!FIELD_GET(REG_MODE_ENA, ctucan_read32(priv, CTUCANFD_MODE))) |
153 | |
154 | /** |
155 | * ctucan_state_to_str() - Converts CAN controller state code to corresponding text |
156 | * @state: CAN controller state code |
157 | * |
158 | * Return: Pointer to string representation of the error state |
159 | */ |
160 | static const char *ctucan_state_to_str(enum can_state state) |
161 | { |
162 | const char *txt = NULL; |
163 | |
164 | if (state >= 0 && state < CAN_STATE_MAX) |
165 | txt = ctucan_state_strings[state]; |
166 | return txt ? txt : "UNKNOWN" ; |
167 | } |
168 | |
169 | /** |
170 | * ctucan_reset() - Issues software reset request to CTU CAN FD |
171 | * @ndev: Pointer to net_device structure |
172 | * |
173 | * Return: 0 for success, -%ETIMEDOUT if CAN controller does not leave reset |
174 | */ |
175 | static int ctucan_reset(struct net_device *ndev) |
176 | { |
177 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
178 | int i = 100; |
179 | |
180 | ctucan_write32(priv, reg: CTUCANFD_MODE, REG_MODE_RST); |
181 | clear_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, addr: &priv->drv_flags); |
182 | |
183 | do { |
184 | u16 device_id = FIELD_GET(REG_DEVICE_ID_DEVICE_ID, |
185 | ctucan_read32(priv, CTUCANFD_DEVICE_ID)); |
186 | |
187 | if (device_id == 0xCAFD) |
188 | return 0; |
189 | if (!i--) { |
190 | netdev_warn(dev: ndev, format: "device did not leave reset\n" ); |
191 | return -ETIMEDOUT; |
192 | } |
193 | usleep_range(min: 100, max: 200); |
194 | } while (1); |
195 | } |
196 | |
197 | /** |
198 | * ctucan_set_btr() - Sets CAN bus bit timing in CTU CAN FD |
199 | * @ndev: Pointer to net_device structure |
200 | * @bt: Pointer to Bit timing structure |
201 | * @nominal: True - Nominal bit timing, False - Data bit timing |
202 | * |
203 | * Return: 0 - OK, -%EPERM if controller is enabled |
204 | */ |
205 | static int ctucan_set_btr(struct net_device *ndev, struct can_bittiming *bt, bool nominal) |
206 | { |
207 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
208 | int max_ph1_len = 31; |
209 | u32 btr = 0; |
210 | u32 prop_seg = bt->prop_seg; |
211 | u32 phase_seg1 = bt->phase_seg1; |
212 | |
213 | if (CTU_CAN_FD_ENABLED(priv)) { |
214 | netdev_err(dev: ndev, format: "BUG! Cannot set bittiming - CAN is enabled\n" ); |
215 | return -EPERM; |
216 | } |
217 | |
218 | if (nominal) |
219 | max_ph1_len = 63; |
220 | |
221 | /* The timing calculation functions have only constraints on tseg1, which is prop_seg + |
222 | * phase1_seg combined. tseg1 is then split in half and stored into prog_seg and phase_seg1. |
223 | * In CTU CAN FD, PROP is 6/7 bits wide but PH1 only 6/5, so we must re-distribute the |
224 | * values here. |
225 | */ |
226 | if (phase_seg1 > max_ph1_len) { |
227 | prop_seg += phase_seg1 - max_ph1_len; |
228 | phase_seg1 = max_ph1_len; |
229 | bt->prop_seg = prop_seg; |
230 | bt->phase_seg1 = phase_seg1; |
231 | } |
232 | |
233 | if (nominal) { |
234 | btr = FIELD_PREP(REG_BTR_PROP, prop_seg); |
235 | btr |= FIELD_PREP(REG_BTR_PH1, phase_seg1); |
236 | btr |= FIELD_PREP(REG_BTR_PH2, bt->phase_seg2); |
237 | btr |= FIELD_PREP(REG_BTR_BRP, bt->brp); |
238 | btr |= FIELD_PREP(REG_BTR_SJW, bt->sjw); |
239 | |
240 | ctucan_write32(priv, reg: CTUCANFD_BTR, val: btr); |
241 | } else { |
242 | btr = FIELD_PREP(REG_BTR_FD_PROP_FD, prop_seg); |
243 | btr |= FIELD_PREP(REG_BTR_FD_PH1_FD, phase_seg1); |
244 | btr |= FIELD_PREP(REG_BTR_FD_PH2_FD, bt->phase_seg2); |
245 | btr |= FIELD_PREP(REG_BTR_FD_BRP_FD, bt->brp); |
246 | btr |= FIELD_PREP(REG_BTR_FD_SJW_FD, bt->sjw); |
247 | |
248 | ctucan_write32(priv, reg: CTUCANFD_BTR_FD, val: btr); |
249 | } |
250 | |
251 | return 0; |
252 | } |
253 | |
254 | /** |
255 | * ctucan_set_bittiming() - CAN set nominal bit timing routine |
256 | * @ndev: Pointer to net_device structure |
257 | * |
258 | * Return: 0 on success, -%EPERM on error |
259 | */ |
260 | static int ctucan_set_bittiming(struct net_device *ndev) |
261 | { |
262 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
263 | struct can_bittiming *bt = &priv->can.bittiming; |
264 | |
265 | /* Note that bt may be modified here */ |
266 | return ctucan_set_btr(ndev, bt, nominal: true); |
267 | } |
268 | |
269 | /** |
270 | * ctucan_set_data_bittiming() - CAN set data bit timing routine |
271 | * @ndev: Pointer to net_device structure |
272 | * |
273 | * Return: 0 on success, -%EPERM on error |
274 | */ |
275 | static int ctucan_set_data_bittiming(struct net_device *ndev) |
276 | { |
277 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
278 | struct can_bittiming *dbt = &priv->can.data_bittiming; |
279 | |
280 | /* Note that dbt may be modified here */ |
281 | return ctucan_set_btr(ndev, bt: dbt, nominal: false); |
282 | } |
283 | |
284 | /** |
285 | * ctucan_set_secondary_sample_point() - Sets secondary sample point in CTU CAN FD |
286 | * @ndev: Pointer to net_device structure |
287 | * |
288 | * Return: 0 on success, -%EPERM if controller is enabled |
289 | */ |
290 | static int ctucan_set_secondary_sample_point(struct net_device *ndev) |
291 | { |
292 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
293 | struct can_bittiming *dbt = &priv->can.data_bittiming; |
294 | int ssp_offset = 0; |
295 | u32 ssp_cfg = 0; /* No SSP by default */ |
296 | |
297 | if (CTU_CAN_FD_ENABLED(priv)) { |
298 | netdev_err(dev: ndev, format: "BUG! Cannot set SSP - CAN is enabled\n" ); |
299 | return -EPERM; |
300 | } |
301 | |
302 | /* Use SSP for bit-rates above 1 Mbits/s */ |
303 | if (dbt->bitrate > 1000000) { |
304 | /* Calculate SSP in minimal time quanta */ |
305 | ssp_offset = (priv->can.clock.freq / 1000) * dbt->sample_point / dbt->bitrate; |
306 | |
307 | if (ssp_offset > 127) { |
308 | netdev_warn(dev: ndev, format: "SSP offset saturated to 127\n" ); |
309 | ssp_offset = 127; |
310 | } |
311 | |
312 | ssp_cfg = FIELD_PREP(REG_TRV_DELAY_SSP_OFFSET, ssp_offset); |
313 | ssp_cfg |= FIELD_PREP(REG_TRV_DELAY_SSP_SRC, 0x1); |
314 | } |
315 | |
316 | ctucan_write32(priv, reg: CTUCANFD_TRV_DELAY, val: ssp_cfg); |
317 | |
318 | return 0; |
319 | } |
320 | |
321 | /** |
322 | * ctucan_set_mode() - Sets CTU CAN FDs mode |
323 | * @priv: Pointer to private data |
324 | * @mode: Pointer to controller modes to be set |
325 | */ |
326 | static void ctucan_set_mode(struct ctucan_priv *priv, const struct can_ctrlmode *mode) |
327 | { |
328 | u32 mode_reg = ctucan_read32(priv, reg: CTUCANFD_MODE); |
329 | |
330 | mode_reg = (mode->flags & CAN_CTRLMODE_LOOPBACK) ? |
331 | (mode_reg | REG_MODE_ILBP) : |
332 | (mode_reg & ~REG_MODE_ILBP); |
333 | |
334 | mode_reg = (mode->flags & CAN_CTRLMODE_LISTENONLY) ? |
335 | (mode_reg | REG_MODE_BMM) : |
336 | (mode_reg & ~REG_MODE_BMM); |
337 | |
338 | mode_reg = (mode->flags & CAN_CTRLMODE_FD) ? |
339 | (mode_reg | REG_MODE_FDE) : |
340 | (mode_reg & ~REG_MODE_FDE); |
341 | |
342 | mode_reg = (mode->flags & CAN_CTRLMODE_PRESUME_ACK) ? |
343 | (mode_reg | REG_MODE_ACF) : |
344 | (mode_reg & ~REG_MODE_ACF); |
345 | |
346 | mode_reg = (mode->flags & CAN_CTRLMODE_FD_NON_ISO) ? |
347 | (mode_reg | REG_MODE_NISOFD) : |
348 | (mode_reg & ~REG_MODE_NISOFD); |
349 | |
350 | /* One shot mode supported indirectly via Retransmit limit */ |
351 | mode_reg &= ~FIELD_PREP(REG_MODE_RTRTH, 0xF); |
352 | mode_reg = (mode->flags & CAN_CTRLMODE_ONE_SHOT) ? |
353 | (mode_reg | REG_MODE_RTRLE) : |
354 | (mode_reg & ~REG_MODE_RTRLE); |
355 | |
356 | /* Some bits fixed: |
357 | * TSTM - Off, User shall not be able to change REC/TEC by hand during operation |
358 | */ |
359 | mode_reg &= ~REG_MODE_TSTM; |
360 | |
361 | ctucan_write32(priv, reg: CTUCANFD_MODE, val: mode_reg); |
362 | } |
363 | |
364 | /** |
365 | * ctucan_chip_start() - This routine starts the driver |
366 | * @ndev: Pointer to net_device structure |
367 | * |
368 | * Routine expects that chip is in reset state. It setups initial |
369 | * Tx buffers for FIFO priorities, sets bittiming, enables interrupts, |
370 | * switches core to operational mode and changes controller |
371 | * state to %CAN_STATE_STOPPED. |
372 | * |
373 | * Return: 0 on success and failure value on error |
374 | */ |
375 | static int ctucan_chip_start(struct net_device *ndev) |
376 | { |
377 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
378 | u32 int_ena, int_msk; |
379 | u32 mode_reg; |
380 | int err; |
381 | struct can_ctrlmode mode; |
382 | |
383 | priv->txb_prio = 0x01234567; |
384 | priv->txb_head = 0; |
385 | priv->txb_tail = 0; |
386 | ctucan_write32(priv, reg: CTUCANFD_TX_PRIORITY, val: priv->txb_prio); |
387 | |
388 | /* Configure bit-rates and ssp */ |
389 | err = ctucan_set_bittiming(ndev); |
390 | if (err < 0) |
391 | return err; |
392 | |
393 | err = ctucan_set_data_bittiming(ndev); |
394 | if (err < 0) |
395 | return err; |
396 | |
397 | err = ctucan_set_secondary_sample_point(ndev); |
398 | if (err < 0) |
399 | return err; |
400 | |
401 | /* Configure modes */ |
402 | mode.flags = priv->can.ctrlmode; |
403 | mode.mask = 0xFFFFFFFF; |
404 | ctucan_set_mode(priv, mode: &mode); |
405 | |
406 | /* Configure interrupts */ |
407 | int_ena = REG_INT_STAT_RBNEI | |
408 | REG_INT_STAT_TXBHCI | |
409 | REG_INT_STAT_EWLI | |
410 | REG_INT_STAT_FCSI; |
411 | |
412 | /* Bus error reporting -> Allow Error/Arb.lost interrupts */ |
413 | if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) { |
414 | int_ena |= REG_INT_STAT_ALI | |
415 | REG_INT_STAT_BEI; |
416 | } |
417 | |
418 | int_msk = ~int_ena; /* Mask all disabled interrupts */ |
419 | |
420 | /* It's after reset, so there is no need to clear anything */ |
421 | ctucan_write32(priv, reg: CTUCANFD_INT_MASK_SET, val: int_msk); |
422 | ctucan_write32(priv, reg: CTUCANFD_INT_ENA_SET, val: int_ena); |
423 | |
424 | /* Controller enters ERROR_ACTIVE on initial FCSI */ |
425 | priv->can.state = CAN_STATE_STOPPED; |
426 | |
427 | /* Enable the controller */ |
428 | mode_reg = ctucan_read32(priv, reg: CTUCANFD_MODE); |
429 | mode_reg |= REG_MODE_ENA; |
430 | ctucan_write32(priv, reg: CTUCANFD_MODE, val: mode_reg); |
431 | |
432 | return 0; |
433 | } |
434 | |
435 | /** |
436 | * ctucan_do_set_mode() - Sets mode of the driver |
437 | * @ndev: Pointer to net_device structure |
438 | * @mode: Tells the mode of the driver |
439 | * |
440 | * This check the drivers state and calls the corresponding modes to set. |
441 | * |
442 | * Return: 0 on success and failure value on error |
443 | */ |
444 | static int ctucan_do_set_mode(struct net_device *ndev, enum can_mode mode) |
445 | { |
446 | int ret; |
447 | |
448 | switch (mode) { |
449 | case CAN_MODE_START: |
450 | ret = ctucan_reset(ndev); |
451 | if (ret < 0) |
452 | return ret; |
453 | ret = ctucan_chip_start(ndev); |
454 | if (ret < 0) { |
455 | netdev_err(dev: ndev, format: "ctucan_chip_start failed!\n" ); |
456 | return ret; |
457 | } |
458 | netif_wake_queue(dev: ndev); |
459 | break; |
460 | default: |
461 | ret = -EOPNOTSUPP; |
462 | break; |
463 | } |
464 | |
465 | return ret; |
466 | } |
467 | |
468 | /** |
469 | * ctucan_get_tx_status() - Gets status of TXT buffer |
470 | * @priv: Pointer to private data |
471 | * @buf: Buffer index (0-based) |
472 | * |
473 | * Return: Status of TXT buffer |
474 | */ |
475 | static enum ctucan_txtb_status ctucan_get_tx_status(struct ctucan_priv *priv, u8 buf) |
476 | { |
477 | u32 tx_status = ctucan_read32(priv, reg: CTUCANFD_TX_STATUS); |
478 | enum ctucan_txtb_status status = (tx_status >> (buf * 4)) & 0x7; |
479 | |
480 | return status; |
481 | } |
482 | |
483 | /** |
484 | * ctucan_is_txt_buf_writable() - Checks if frame can be inserted to TXT Buffer |
485 | * @priv: Pointer to private data |
486 | * @buf: Buffer index (0-based) |
487 | * |
488 | * Return: True - Frame can be inserted to TXT Buffer, False - If attempted, frame will not be |
489 | * inserted to TXT Buffer |
490 | */ |
491 | static bool ctucan_is_txt_buf_writable(struct ctucan_priv *priv, u8 buf) |
492 | { |
493 | enum ctucan_txtb_status buf_status; |
494 | |
495 | buf_status = ctucan_get_tx_status(priv, buf); |
496 | if (buf_status == TXT_RDY || buf_status == TXT_TRAN || buf_status == TXT_ABTP) |
497 | return false; |
498 | |
499 | return true; |
500 | } |
501 | |
502 | /** |
503 | * ctucan_insert_frame() - Inserts frame to TXT buffer |
504 | * @priv: Pointer to private data |
505 | * @cf: Pointer to CAN frame to be inserted |
506 | * @buf: TXT Buffer index to which frame is inserted (0-based) |
507 | * @isfdf: True - CAN FD Frame, False - CAN 2.0 Frame |
508 | * |
509 | * Return: True - Frame inserted successfully |
510 | * False - Frame was not inserted due to one of: |
511 | * 1. TXT Buffer is not writable (it is in wrong state) |
512 | * 2. Invalid TXT buffer index |
513 | * 3. Invalid frame length |
514 | */ |
515 | static bool ctucan_insert_frame(struct ctucan_priv *priv, const struct canfd_frame *cf, u8 buf, |
516 | bool isfdf) |
517 | { |
518 | u32 buf_base; |
519 | u32 ffw = 0; |
520 | u32 idw = 0; |
521 | unsigned int i; |
522 | |
523 | if (buf >= priv->ntxbufs) |
524 | return false; |
525 | |
526 | if (!ctucan_is_txt_buf_writable(priv, buf)) |
527 | return false; |
528 | |
529 | if (cf->len > CANFD_MAX_DLEN) |
530 | return false; |
531 | |
532 | /* Prepare Frame format */ |
533 | if (cf->can_id & CAN_RTR_FLAG) |
534 | ffw |= REG_FRAME_FORMAT_W_RTR; |
535 | |
536 | if (cf->can_id & CAN_EFF_FLAG) |
537 | ffw |= REG_FRAME_FORMAT_W_IDE; |
538 | |
539 | if (isfdf) { |
540 | ffw |= REG_FRAME_FORMAT_W_FDF; |
541 | if (cf->flags & CANFD_BRS) |
542 | ffw |= REG_FRAME_FORMAT_W_BRS; |
543 | } |
544 | |
545 | ffw |= FIELD_PREP(REG_FRAME_FORMAT_W_DLC, can_fd_len2dlc(cf->len)); |
546 | |
547 | /* Prepare identifier */ |
548 | if (cf->can_id & CAN_EFF_FLAG) |
549 | idw = cf->can_id & CAN_EFF_MASK; |
550 | else |
551 | idw = FIELD_PREP(REG_IDENTIFIER_W_IDENTIFIER_BASE, cf->can_id & CAN_SFF_MASK); |
552 | |
553 | /* Write ID, Frame format, Don't write timestamp -> Time triggered transmission disabled */ |
554 | buf_base = (buf + 1) * 0x100; |
555 | ctucan_write_txt_buf(priv, buf_base, offset: CTUCANFD_FRAME_FORMAT_W, val: ffw); |
556 | ctucan_write_txt_buf(priv, buf_base, offset: CTUCANFD_IDENTIFIER_W, val: idw); |
557 | |
558 | /* Write Data payload */ |
559 | if (!(cf->can_id & CAN_RTR_FLAG)) { |
560 | for (i = 0; i < cf->len; i += 4) { |
561 | u32 data = le32_to_cpu(*(__le32 *)(cf->data + i)); |
562 | |
563 | ctucan_write_txt_buf(priv, buf_base, offset: CTUCANFD_DATA_1_4_W + i, val: data); |
564 | } |
565 | } |
566 | |
567 | return true; |
568 | } |
569 | |
570 | /** |
571 | * ctucan_give_txtb_cmd() - Applies command on TXT buffer |
572 | * @priv: Pointer to private data |
573 | * @cmd: Command to give |
574 | * @buf: Buffer index (0-based) |
575 | */ |
576 | static void ctucan_give_txtb_cmd(struct ctucan_priv *priv, enum ctucan_txtb_command cmd, u8 buf) |
577 | { |
578 | u32 tx_cmd = cmd; |
579 | |
580 | tx_cmd |= 1 << (buf + 8); |
581 | ctucan_write32(priv, reg: CTUCANFD_TX_COMMAND, val: tx_cmd); |
582 | } |
583 | |
584 | /** |
585 | * ctucan_start_xmit() - Starts the transmission |
586 | * @skb: sk_buff pointer that contains data to be Txed |
587 | * @ndev: Pointer to net_device structure |
588 | * |
589 | * Invoked from upper layers to initiate transmission. Uses the next available free TXT Buffer and |
590 | * populates its fields to start the transmission. |
591 | * |
592 | * Return: %NETDEV_TX_OK on success, %NETDEV_TX_BUSY when no free TXT buffer is available, |
593 | * negative return values reserved for error cases |
594 | */ |
595 | static netdev_tx_t ctucan_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
596 | { |
597 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
598 | struct canfd_frame *cf = (struct canfd_frame *)skb->data; |
599 | u32 txtb_id; |
600 | bool ok; |
601 | unsigned long flags; |
602 | |
603 | if (can_dev_dropped_skb(dev: ndev, skb)) |
604 | return NETDEV_TX_OK; |
605 | |
606 | if (unlikely(!CTU_CAN_FD_TXTNF(priv))) { |
607 | netif_stop_queue(dev: ndev); |
608 | netdev_err(dev: ndev, format: "BUG!, no TXB free when queue awake!\n" ); |
609 | return NETDEV_TX_BUSY; |
610 | } |
611 | |
612 | txtb_id = priv->txb_head % priv->ntxbufs; |
613 | ctucan_netdev_dbg(ndev, "%s: using TXB#%u\n" , __func__, txtb_id); |
614 | ok = ctucan_insert_frame(priv, cf, buf: txtb_id, isfdf: can_is_canfd_skb(skb)); |
615 | |
616 | if (!ok) { |
617 | netdev_err(dev: ndev, format: "BUG! TXNF set but cannot insert frame into TXTB! HW Bug?" ); |
618 | kfree_skb(skb); |
619 | ndev->stats.tx_dropped++; |
620 | return NETDEV_TX_OK; |
621 | } |
622 | |
623 | can_put_echo_skb(skb, dev: ndev, idx: txtb_id, frame_len: 0); |
624 | |
625 | spin_lock_irqsave(&priv->tx_lock, flags); |
626 | ctucan_give_txtb_cmd(priv, cmd: TXT_CMD_SET_READY, buf: txtb_id); |
627 | priv->txb_head++; |
628 | |
629 | /* Check if all TX buffers are full */ |
630 | if (!CTU_CAN_FD_TXTNF(priv)) |
631 | netif_stop_queue(dev: ndev); |
632 | |
633 | spin_unlock_irqrestore(lock: &priv->tx_lock, flags); |
634 | |
635 | return NETDEV_TX_OK; |
636 | } |
637 | |
638 | /** |
639 | * ctucan_read_rx_frame() - Reads frame from RX FIFO |
640 | * @priv: Pointer to CTU CAN FD's private data |
641 | * @cf: Pointer to CAN frame struct |
642 | * @ffw: Previously read frame format word |
643 | * |
644 | * Note: Frame format word must be read separately and provided in 'ffw'. |
645 | */ |
646 | static void ctucan_read_rx_frame(struct ctucan_priv *priv, struct canfd_frame *cf, u32 ffw) |
647 | { |
648 | u32 idw; |
649 | unsigned int i; |
650 | unsigned int wc; |
651 | unsigned int len; |
652 | |
653 | idw = ctucan_read32(priv, reg: CTUCANFD_RX_DATA); |
654 | if (FIELD_GET(REG_FRAME_FORMAT_W_IDE, ffw)) |
655 | cf->can_id = (idw & CAN_EFF_MASK) | CAN_EFF_FLAG; |
656 | else |
657 | cf->can_id = (idw >> 18) & CAN_SFF_MASK; |
658 | |
659 | /* BRS, ESI, RTR Flags */ |
660 | if (FIELD_GET(REG_FRAME_FORMAT_W_FDF, ffw)) { |
661 | if (FIELD_GET(REG_FRAME_FORMAT_W_BRS, ffw)) |
662 | cf->flags |= CANFD_BRS; |
663 | if (FIELD_GET(REG_FRAME_FORMAT_W_ESI_RSV, ffw)) |
664 | cf->flags |= CANFD_ESI; |
665 | } else if (FIELD_GET(REG_FRAME_FORMAT_W_RTR, ffw)) { |
666 | cf->can_id |= CAN_RTR_FLAG; |
667 | } |
668 | |
669 | wc = FIELD_GET(REG_FRAME_FORMAT_W_RWCNT, ffw) - 3; |
670 | |
671 | /* DLC */ |
672 | if (FIELD_GET(REG_FRAME_FORMAT_W_DLC, ffw) <= 8) { |
673 | len = FIELD_GET(REG_FRAME_FORMAT_W_DLC, ffw); |
674 | } else { |
675 | if (FIELD_GET(REG_FRAME_FORMAT_W_FDF, ffw)) |
676 | len = wc << 2; |
677 | else |
678 | len = 8; |
679 | } |
680 | cf->len = len; |
681 | if (unlikely(len > wc * 4)) |
682 | len = wc * 4; |
683 | |
684 | /* Timestamp - Read and throw away */ |
685 | ctucan_read32(priv, reg: CTUCANFD_RX_DATA); |
686 | ctucan_read32(priv, reg: CTUCANFD_RX_DATA); |
687 | |
688 | /* Data */ |
689 | for (i = 0; i < len; i += 4) { |
690 | u32 data = ctucan_read32(priv, reg: CTUCANFD_RX_DATA); |
691 | *(__le32 *)(cf->data + i) = cpu_to_le32(data); |
692 | } |
693 | while (unlikely(i < wc * 4)) { |
694 | ctucan_read32(priv, reg: CTUCANFD_RX_DATA); |
695 | i += 4; |
696 | } |
697 | } |
698 | |
699 | /** |
700 | * ctucan_rx() - Called from CAN ISR to complete the received frame processing |
701 | * @ndev: Pointer to net_device structure |
702 | * |
703 | * This function is invoked from the CAN isr(poll) to process the Rx frames. It does minimal |
704 | * processing and invokes "netif_receive_skb" to complete further processing. |
705 | * Return: 1 when frame is passed to the network layer, 0 when the first frame word is read but |
706 | * system is out of free SKBs temporally and left code to resolve SKB allocation later, |
707 | * -%EAGAIN in a case of empty Rx FIFO. |
708 | */ |
709 | static int ctucan_rx(struct net_device *ndev) |
710 | { |
711 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
712 | struct net_device_stats *stats = &ndev->stats; |
713 | struct canfd_frame *cf; |
714 | struct sk_buff *skb; |
715 | u32 ffw; |
716 | |
717 | if (test_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, &priv->drv_flags)) { |
718 | ffw = priv->rxfrm_first_word; |
719 | clear_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, addr: &priv->drv_flags); |
720 | } else { |
721 | ffw = ctucan_read32(priv, reg: CTUCANFD_RX_DATA); |
722 | } |
723 | |
724 | if (!FIELD_GET(REG_FRAME_FORMAT_W_RWCNT, ffw)) |
725 | return -EAGAIN; |
726 | |
727 | if (FIELD_GET(REG_FRAME_FORMAT_W_FDF, ffw)) |
728 | skb = alloc_canfd_skb(dev: ndev, cfd: &cf); |
729 | else |
730 | skb = alloc_can_skb(dev: ndev, cf: (struct can_frame **)&cf); |
731 | |
732 | if (unlikely(!skb)) { |
733 | priv->rxfrm_first_word = ffw; |
734 | set_bit(CTUCANFD_FLAG_RX_FFW_BUFFERED, addr: &priv->drv_flags); |
735 | return 0; |
736 | } |
737 | |
738 | ctucan_read_rx_frame(priv, cf, ffw); |
739 | |
740 | stats->rx_bytes += cf->len; |
741 | stats->rx_packets++; |
742 | netif_receive_skb(skb); |
743 | |
744 | return 1; |
745 | } |
746 | |
747 | /** |
748 | * ctucan_read_fault_state() - Reads CTU CAN FDs fault confinement state. |
749 | * @priv: Pointer to private data |
750 | * |
751 | * Returns: Fault confinement state of controller |
752 | */ |
753 | static enum can_state ctucan_read_fault_state(struct ctucan_priv *priv) |
754 | { |
755 | u32 fs; |
756 | u32 rec_tec; |
757 | u32 ewl; |
758 | |
759 | fs = ctucan_read32(priv, reg: CTUCANFD_EWL); |
760 | rec_tec = ctucan_read32(priv, reg: CTUCANFD_REC); |
761 | ewl = FIELD_GET(REG_EWL_EW_LIMIT, fs); |
762 | |
763 | if (FIELD_GET(REG_EWL_ERA, fs)) { |
764 | if (ewl > FIELD_GET(REG_REC_REC_VAL, rec_tec) && |
765 | ewl > FIELD_GET(REG_REC_TEC_VAL, rec_tec)) |
766 | return CAN_STATE_ERROR_ACTIVE; |
767 | else |
768 | return CAN_STATE_ERROR_WARNING; |
769 | } else if (FIELD_GET(REG_EWL_ERP, fs)) { |
770 | return CAN_STATE_ERROR_PASSIVE; |
771 | } else if (FIELD_GET(REG_EWL_BOF, fs)) { |
772 | return CAN_STATE_BUS_OFF; |
773 | } |
774 | |
775 | WARN(true, "Invalid error state" ); |
776 | return CAN_STATE_ERROR_PASSIVE; |
777 | } |
778 | |
779 | /** |
780 | * ctucan_get_rec_tec() - Reads REC/TEC counter values from controller |
781 | * @priv: Pointer to private data |
782 | * @bec: Pointer to Error counter structure |
783 | */ |
784 | static void ctucan_get_rec_tec(struct ctucan_priv *priv, struct can_berr_counter *bec) |
785 | { |
786 | u32 err_ctrs = ctucan_read32(priv, reg: CTUCANFD_REC); |
787 | |
788 | bec->rxerr = FIELD_GET(REG_REC_REC_VAL, err_ctrs); |
789 | bec->txerr = FIELD_GET(REG_REC_TEC_VAL, err_ctrs); |
790 | } |
791 | |
792 | /** |
793 | * ctucan_err_interrupt() - Error frame ISR |
794 | * @ndev: net_device pointer |
795 | * @isr: interrupt status register value |
796 | * |
797 | * This is the CAN error interrupt and it will check the type of error and forward the error |
798 | * frame to upper layers. |
799 | */ |
800 | static void ctucan_err_interrupt(struct net_device *ndev, u32 isr) |
801 | { |
802 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
803 | struct net_device_stats *stats = &ndev->stats; |
804 | struct can_frame *cf; |
805 | struct sk_buff *skb; |
806 | enum can_state state; |
807 | struct can_berr_counter bec; |
808 | u32 err_capt_alc; |
809 | int dologerr = net_ratelimit(); |
810 | |
811 | ctucan_get_rec_tec(priv, bec: &bec); |
812 | state = ctucan_read_fault_state(priv); |
813 | err_capt_alc = ctucan_read32(priv, reg: CTUCANFD_ERR_CAPT); |
814 | |
815 | if (dologerr) |
816 | netdev_info(dev: ndev, format: "%s: ISR = 0x%08x, rxerr %d, txerr %d, error type %lu, pos %lu, ALC id_field %lu, bit %lu\n" , |
817 | __func__, isr, bec.rxerr, bec.txerr, |
818 | FIELD_GET(REG_ERR_CAPT_ERR_TYPE, err_capt_alc), |
819 | FIELD_GET(REG_ERR_CAPT_ERR_POS, err_capt_alc), |
820 | FIELD_GET(REG_ERR_CAPT_ALC_ID_FIELD, err_capt_alc), |
821 | FIELD_GET(REG_ERR_CAPT_ALC_BIT, err_capt_alc)); |
822 | |
823 | skb = alloc_can_err_skb(dev: ndev, cf: &cf); |
824 | |
825 | /* EWLI: error warning limit condition met |
826 | * FCSI: fault confinement state changed |
827 | * ALI: arbitration lost (just informative) |
828 | * BEI: bus error interrupt |
829 | */ |
830 | if (FIELD_GET(REG_INT_STAT_FCSI, isr) || FIELD_GET(REG_INT_STAT_EWLI, isr)) { |
831 | netdev_info(dev: ndev, format: "state changes from %s to %s\n" , |
832 | ctucan_state_to_str(state: priv->can.state), |
833 | ctucan_state_to_str(state)); |
834 | |
835 | if (priv->can.state == state) |
836 | netdev_warn(dev: ndev, |
837 | format: "current and previous state is the same! (missed interrupt?)\n" ); |
838 | |
839 | priv->can.state = state; |
840 | switch (state) { |
841 | case CAN_STATE_BUS_OFF: |
842 | priv->can.can_stats.bus_off++; |
843 | can_bus_off(dev: ndev); |
844 | if (skb) |
845 | cf->can_id |= CAN_ERR_BUSOFF; |
846 | break; |
847 | case CAN_STATE_ERROR_PASSIVE: |
848 | priv->can.can_stats.error_passive++; |
849 | if (skb) { |
850 | cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; |
851 | cf->data[1] = (bec.rxerr > 127) ? |
852 | CAN_ERR_CRTL_RX_PASSIVE : |
853 | CAN_ERR_CRTL_TX_PASSIVE; |
854 | cf->data[6] = bec.txerr; |
855 | cf->data[7] = bec.rxerr; |
856 | } |
857 | break; |
858 | case CAN_STATE_ERROR_WARNING: |
859 | priv->can.can_stats.error_warning++; |
860 | if (skb) { |
861 | cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; |
862 | cf->data[1] |= (bec.txerr > bec.rxerr) ? |
863 | CAN_ERR_CRTL_TX_WARNING : |
864 | CAN_ERR_CRTL_RX_WARNING; |
865 | cf->data[6] = bec.txerr; |
866 | cf->data[7] = bec.rxerr; |
867 | } |
868 | break; |
869 | case CAN_STATE_ERROR_ACTIVE: |
870 | cf->can_id |= CAN_ERR_CNT; |
871 | cf->data[1] = CAN_ERR_CRTL_ACTIVE; |
872 | cf->data[6] = bec.txerr; |
873 | cf->data[7] = bec.rxerr; |
874 | break; |
875 | default: |
876 | netdev_warn(dev: ndev, format: "unhandled error state (%d:%s)!\n" , |
877 | state, ctucan_state_to_str(state)); |
878 | break; |
879 | } |
880 | } |
881 | |
882 | /* Check for Arbitration Lost interrupt */ |
883 | if (FIELD_GET(REG_INT_STAT_ALI, isr)) { |
884 | if (dologerr) |
885 | netdev_info(dev: ndev, format: "arbitration lost\n" ); |
886 | priv->can.can_stats.arbitration_lost++; |
887 | if (skb) { |
888 | cf->can_id |= CAN_ERR_LOSTARB; |
889 | cf->data[0] = CAN_ERR_LOSTARB_UNSPEC; |
890 | } |
891 | } |
892 | |
893 | /* Check for Bus Error interrupt */ |
894 | if (FIELD_GET(REG_INT_STAT_BEI, isr)) { |
895 | netdev_info(dev: ndev, format: "bus error\n" ); |
896 | priv->can.can_stats.bus_error++; |
897 | stats->rx_errors++; |
898 | if (skb) { |
899 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
900 | cf->data[2] = CAN_ERR_PROT_UNSPEC; |
901 | cf->data[3] = CAN_ERR_PROT_LOC_UNSPEC; |
902 | } |
903 | } |
904 | |
905 | if (skb) { |
906 | stats->rx_packets++; |
907 | stats->rx_bytes += cf->can_dlc; |
908 | netif_rx(skb); |
909 | } |
910 | } |
911 | |
912 | /** |
913 | * ctucan_rx_poll() - Poll routine for rx packets (NAPI) |
914 | * @napi: NAPI structure pointer |
915 | * @quota: Max number of rx packets to be processed. |
916 | * |
917 | * This is the poll routine for rx part. It will process the packets maximux quota value. |
918 | * |
919 | * Return: Number of packets received |
920 | */ |
921 | static int ctucan_rx_poll(struct napi_struct *napi, int quota) |
922 | { |
923 | struct net_device *ndev = napi->dev; |
924 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
925 | int work_done = 0; |
926 | u32 status; |
927 | u32 framecnt; |
928 | int res = 1; |
929 | |
930 | framecnt = FIELD_GET(REG_RX_STATUS_RXFRC, ctucan_read32(priv, CTUCANFD_RX_STATUS)); |
931 | while (framecnt && work_done < quota && res > 0) { |
932 | res = ctucan_rx(ndev); |
933 | work_done++; |
934 | framecnt = FIELD_GET(REG_RX_STATUS_RXFRC, ctucan_read32(priv, CTUCANFD_RX_STATUS)); |
935 | } |
936 | |
937 | /* Check for RX FIFO Overflow */ |
938 | status = ctucan_read32(priv, reg: CTUCANFD_STATUS); |
939 | if (FIELD_GET(REG_STATUS_DOR, status)) { |
940 | struct net_device_stats *stats = &ndev->stats; |
941 | struct can_frame *cf; |
942 | struct sk_buff *skb; |
943 | |
944 | netdev_info(dev: ndev, format: "rx_poll: rx fifo overflow\n" ); |
945 | stats->rx_over_errors++; |
946 | stats->rx_errors++; |
947 | skb = alloc_can_err_skb(dev: ndev, cf: &cf); |
948 | if (skb) { |
949 | cf->can_id |= CAN_ERR_CRTL; |
950 | cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; |
951 | stats->rx_packets++; |
952 | stats->rx_bytes += cf->can_dlc; |
953 | netif_rx(skb); |
954 | } |
955 | |
956 | /* Clear Data Overrun */ |
957 | ctucan_write32(priv, reg: CTUCANFD_COMMAND, REG_COMMAND_CDO); |
958 | } |
959 | |
960 | if (!framecnt && res != 0) { |
961 | if (napi_complete_done(n: napi, work_done)) { |
962 | /* Clear and enable RBNEI. It is level-triggered, so |
963 | * there is no race condition. |
964 | */ |
965 | ctucan_write32(priv, reg: CTUCANFD_INT_STAT, REG_INT_STAT_RBNEI); |
966 | ctucan_write32(priv, reg: CTUCANFD_INT_MASK_CLR, REG_INT_STAT_RBNEI); |
967 | } |
968 | } |
969 | |
970 | return work_done; |
971 | } |
972 | |
973 | /** |
974 | * ctucan_rotate_txb_prio() - Rotates priorities of TXT Buffers |
975 | * @ndev: net_device pointer |
976 | */ |
977 | static void ctucan_rotate_txb_prio(struct net_device *ndev) |
978 | { |
979 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
980 | u32 prio = priv->txb_prio; |
981 | |
982 | prio = (prio << 4) | ((prio >> ((priv->ntxbufs - 1) * 4)) & 0xF); |
983 | ctucan_netdev_dbg(ndev, "%s: from 0x%08x to 0x%08x\n" , __func__, priv->txb_prio, prio); |
984 | priv->txb_prio = prio; |
985 | ctucan_write32(priv, reg: CTUCANFD_TX_PRIORITY, val: prio); |
986 | } |
987 | |
988 | /** |
989 | * ctucan_tx_interrupt() - Tx done Isr |
990 | * @ndev: net_device pointer |
991 | */ |
992 | static void ctucan_tx_interrupt(struct net_device *ndev) |
993 | { |
994 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
995 | struct net_device_stats *stats = &ndev->stats; |
996 | bool first = true; |
997 | bool some_buffers_processed; |
998 | unsigned long flags; |
999 | enum ctucan_txtb_status txtb_status; |
1000 | u32 txtb_id; |
1001 | |
1002 | /* read tx_status |
1003 | * if txb[n].finished (bit 2) |
1004 | * if ok -> echo |
1005 | * if error / aborted -> ?? (find how to handle oneshot mode) |
1006 | * txb_tail++ |
1007 | */ |
1008 | do { |
1009 | spin_lock_irqsave(&priv->tx_lock, flags); |
1010 | |
1011 | some_buffers_processed = false; |
1012 | while ((int)(priv->txb_head - priv->txb_tail) > 0) { |
1013 | txtb_id = priv->txb_tail % priv->ntxbufs; |
1014 | txtb_status = ctucan_get_tx_status(priv, buf: txtb_id); |
1015 | |
1016 | ctucan_netdev_dbg(ndev, "TXI: TXB#%u: status 0x%x\n" , txtb_id, txtb_status); |
1017 | |
1018 | switch (txtb_status) { |
1019 | case TXT_TOK: |
1020 | ctucan_netdev_dbg(ndev, "TXT_OK\n" ); |
1021 | stats->tx_bytes += can_get_echo_skb(dev: ndev, idx: txtb_id, NULL); |
1022 | stats->tx_packets++; |
1023 | break; |
1024 | case TXT_ERR: |
1025 | /* This indicated that retransmit limit has been reached. Obviously |
1026 | * we should not echo the frame, but also not indicate any kind of |
1027 | * error. If desired, it was already reported (possible multiple |
1028 | * times) on each arbitration lost. |
1029 | */ |
1030 | netdev_warn(dev: ndev, format: "TXB in Error state\n" ); |
1031 | can_free_echo_skb(dev: ndev, idx: txtb_id, NULL); |
1032 | stats->tx_dropped++; |
1033 | break; |
1034 | case TXT_ABT: |
1035 | /* Same as for TXT_ERR, only with different cause. We *could* |
1036 | * re-queue the frame, but multiqueue/abort is not supported yet |
1037 | * anyway. |
1038 | */ |
1039 | netdev_warn(dev: ndev, format: "TXB in Aborted state\n" ); |
1040 | can_free_echo_skb(dev: ndev, idx: txtb_id, NULL); |
1041 | stats->tx_dropped++; |
1042 | break; |
1043 | default: |
1044 | /* Bug only if the first buffer is not finished, otherwise it is |
1045 | * pretty much expected. |
1046 | */ |
1047 | if (first) { |
1048 | netdev_err(dev: ndev, |
1049 | format: "BUG: TXB#%u not in a finished state (0x%x)!\n" , |
1050 | txtb_id, txtb_status); |
1051 | spin_unlock_irqrestore(lock: &priv->tx_lock, flags); |
1052 | /* do not clear nor wake */ |
1053 | return; |
1054 | } |
1055 | goto clear; |
1056 | } |
1057 | priv->txb_tail++; |
1058 | first = false; |
1059 | some_buffers_processed = true; |
1060 | /* Adjust priorities *before* marking the buffer as empty. */ |
1061 | ctucan_rotate_txb_prio(ndev); |
1062 | ctucan_give_txtb_cmd(priv, cmd: TXT_CMD_SET_EMPTY, buf: txtb_id); |
1063 | } |
1064 | clear: |
1065 | spin_unlock_irqrestore(lock: &priv->tx_lock, flags); |
1066 | |
1067 | /* If no buffers were processed this time, we cannot clear - that would introduce |
1068 | * a race condition. |
1069 | */ |
1070 | if (some_buffers_processed) { |
1071 | /* Clear the interrupt again. We do not want to receive again interrupt for |
1072 | * the buffer already handled. If it is the last finished one then it would |
1073 | * cause log of spurious interrupt. |
1074 | */ |
1075 | ctucan_write32(priv, reg: CTUCANFD_INT_STAT, REG_INT_STAT_TXBHCI); |
1076 | } |
1077 | } while (some_buffers_processed); |
1078 | |
1079 | spin_lock_irqsave(&priv->tx_lock, flags); |
1080 | |
1081 | /* Check if at least one TX buffer is free */ |
1082 | if (CTU_CAN_FD_TXTNF(priv)) |
1083 | netif_wake_queue(dev: ndev); |
1084 | |
1085 | spin_unlock_irqrestore(lock: &priv->tx_lock, flags); |
1086 | } |
1087 | |
1088 | /** |
1089 | * ctucan_interrupt() - CAN Isr |
1090 | * @irq: irq number |
1091 | * @dev_id: device id pointer |
1092 | * |
1093 | * This is the CTU CAN FD ISR. It checks for the type of interrupt |
1094 | * and invokes the corresponding ISR. |
1095 | * |
1096 | * Return: |
1097 | * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise |
1098 | */ |
1099 | static irqreturn_t ctucan_interrupt(int irq, void *dev_id) |
1100 | { |
1101 | struct net_device *ndev = (struct net_device *)dev_id; |
1102 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
1103 | u32 isr, icr; |
1104 | u32 imask; |
1105 | int irq_loops; |
1106 | |
1107 | for (irq_loops = 0; irq_loops < 10000; irq_loops++) { |
1108 | /* Get the interrupt status */ |
1109 | isr = ctucan_read32(priv, reg: CTUCANFD_INT_STAT); |
1110 | |
1111 | if (!isr) |
1112 | return irq_loops ? IRQ_HANDLED : IRQ_NONE; |
1113 | |
1114 | /* Receive Buffer Not Empty Interrupt */ |
1115 | if (FIELD_GET(REG_INT_STAT_RBNEI, isr)) { |
1116 | ctucan_netdev_dbg(ndev, "RXBNEI\n" ); |
1117 | /* Mask RXBNEI the first, then clear interrupt and schedule NAPI. Even if |
1118 | * another IRQ fires, RBNEI will always be 0 (masked). |
1119 | */ |
1120 | icr = REG_INT_STAT_RBNEI; |
1121 | ctucan_write32(priv, reg: CTUCANFD_INT_MASK_SET, val: icr); |
1122 | ctucan_write32(priv, reg: CTUCANFD_INT_STAT, val: icr); |
1123 | napi_schedule(n: &priv->napi); |
1124 | } |
1125 | |
1126 | /* TXT Buffer HW Command Interrupt */ |
1127 | if (FIELD_GET(REG_INT_STAT_TXBHCI, isr)) { |
1128 | ctucan_netdev_dbg(ndev, "TXBHCI\n" ); |
1129 | /* Cleared inside */ |
1130 | ctucan_tx_interrupt(ndev); |
1131 | } |
1132 | |
1133 | /* Error interrupts */ |
1134 | if (FIELD_GET(REG_INT_STAT_EWLI, isr) || |
1135 | FIELD_GET(REG_INT_STAT_FCSI, isr) || |
1136 | FIELD_GET(REG_INT_STAT_ALI, isr)) { |
1137 | icr = isr & (REG_INT_STAT_EWLI | REG_INT_STAT_FCSI | REG_INT_STAT_ALI); |
1138 | |
1139 | ctucan_netdev_dbg(ndev, "some ERR interrupt: clearing 0x%08x\n" , icr); |
1140 | ctucan_write32(priv, reg: CTUCANFD_INT_STAT, val: icr); |
1141 | ctucan_err_interrupt(ndev, isr); |
1142 | } |
1143 | /* Ignore RI, TI, LFI, RFI, BSI */ |
1144 | } |
1145 | |
1146 | netdev_err(dev: ndev, format: "%s: stuck interrupt (isr=0x%08x), stopping\n" , __func__, isr); |
1147 | |
1148 | if (FIELD_GET(REG_INT_STAT_TXBHCI, isr)) { |
1149 | int i; |
1150 | |
1151 | netdev_err(dev: ndev, format: "txb_head=0x%08x txb_tail=0x%08x\n" , |
1152 | priv->txb_head, priv->txb_tail); |
1153 | for (i = 0; i < priv->ntxbufs; i++) { |
1154 | u32 status = ctucan_get_tx_status(priv, buf: i); |
1155 | |
1156 | netdev_err(dev: ndev, format: "txb[%d] txb status=0x%08x\n" , i, status); |
1157 | } |
1158 | } |
1159 | |
1160 | imask = 0xffffffff; |
1161 | ctucan_write32(priv, reg: CTUCANFD_INT_ENA_CLR, val: imask); |
1162 | ctucan_write32(priv, reg: CTUCANFD_INT_MASK_SET, val: imask); |
1163 | |
1164 | return IRQ_HANDLED; |
1165 | } |
1166 | |
1167 | /** |
1168 | * ctucan_chip_stop() - Driver stop routine |
1169 | * @ndev: Pointer to net_device structure |
1170 | * |
1171 | * This is the drivers stop routine. It will disable the |
1172 | * interrupts and disable the controller. |
1173 | */ |
1174 | static void ctucan_chip_stop(struct net_device *ndev) |
1175 | { |
1176 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
1177 | u32 mask = 0xffffffff; |
1178 | u32 mode; |
1179 | |
1180 | /* Disable interrupts and disable CAN */ |
1181 | ctucan_write32(priv, reg: CTUCANFD_INT_ENA_CLR, val: mask); |
1182 | ctucan_write32(priv, reg: CTUCANFD_INT_MASK_SET, val: mask); |
1183 | mode = ctucan_read32(priv, reg: CTUCANFD_MODE); |
1184 | mode &= ~REG_MODE_ENA; |
1185 | ctucan_write32(priv, reg: CTUCANFD_MODE, val: mode); |
1186 | |
1187 | priv->can.state = CAN_STATE_STOPPED; |
1188 | } |
1189 | |
1190 | /** |
1191 | * ctucan_open() - Driver open routine |
1192 | * @ndev: Pointer to net_device structure |
1193 | * |
1194 | * This is the driver open routine. |
1195 | * Return: 0 on success and failure value on error |
1196 | */ |
1197 | static int ctucan_open(struct net_device *ndev) |
1198 | { |
1199 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
1200 | int ret; |
1201 | |
1202 | ret = pm_runtime_get_sync(dev: priv->dev); |
1203 | if (ret < 0) { |
1204 | netdev_err(dev: ndev, format: "%s: pm_runtime_get failed(%d)\n" , |
1205 | __func__, ret); |
1206 | pm_runtime_put_noidle(dev: priv->dev); |
1207 | return ret; |
1208 | } |
1209 | |
1210 | ret = ctucan_reset(ndev); |
1211 | if (ret < 0) |
1212 | goto err_reset; |
1213 | |
1214 | /* Common open */ |
1215 | ret = open_candev(dev: ndev); |
1216 | if (ret) { |
1217 | netdev_warn(dev: ndev, format: "open_candev failed!\n" ); |
1218 | goto err_open; |
1219 | } |
1220 | |
1221 | ret = request_irq(irq: ndev->irq, handler: ctucan_interrupt, flags: priv->irq_flags, name: ndev->name, dev: ndev); |
1222 | if (ret < 0) { |
1223 | netdev_err(dev: ndev, format: "irq allocation for CAN failed\n" ); |
1224 | goto err_irq; |
1225 | } |
1226 | |
1227 | ret = ctucan_chip_start(ndev); |
1228 | if (ret < 0) { |
1229 | netdev_err(dev: ndev, format: "ctucan_chip_start failed!\n" ); |
1230 | goto err_chip_start; |
1231 | } |
1232 | |
1233 | netdev_info(dev: ndev, format: "ctu_can_fd device registered\n" ); |
1234 | napi_enable(n: &priv->napi); |
1235 | netif_start_queue(dev: ndev); |
1236 | |
1237 | return 0; |
1238 | |
1239 | err_chip_start: |
1240 | free_irq(ndev->irq, ndev); |
1241 | err_irq: |
1242 | close_candev(dev: ndev); |
1243 | err_open: |
1244 | err_reset: |
1245 | pm_runtime_put(dev: priv->dev); |
1246 | |
1247 | return ret; |
1248 | } |
1249 | |
1250 | /** |
1251 | * ctucan_close() - Driver close routine |
1252 | * @ndev: Pointer to net_device structure |
1253 | * |
1254 | * Return: 0 always |
1255 | */ |
1256 | static int ctucan_close(struct net_device *ndev) |
1257 | { |
1258 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
1259 | |
1260 | netif_stop_queue(dev: ndev); |
1261 | napi_disable(n: &priv->napi); |
1262 | ctucan_chip_stop(ndev); |
1263 | free_irq(ndev->irq, ndev); |
1264 | close_candev(dev: ndev); |
1265 | |
1266 | pm_runtime_put(dev: priv->dev); |
1267 | |
1268 | return 0; |
1269 | } |
1270 | |
1271 | /** |
1272 | * ctucan_get_berr_counter() - error counter routine |
1273 | * @ndev: Pointer to net_device structure |
1274 | * @bec: Pointer to can_berr_counter structure |
1275 | * |
1276 | * This is the driver error counter routine. |
1277 | * Return: 0 on success and failure value on error |
1278 | */ |
1279 | static int ctucan_get_berr_counter(const struct net_device *ndev, struct can_berr_counter *bec) |
1280 | { |
1281 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
1282 | int ret; |
1283 | |
1284 | ret = pm_runtime_get_sync(dev: priv->dev); |
1285 | if (ret < 0) { |
1286 | netdev_err(dev: ndev, format: "%s: pm_runtime_get failed(%d)\n" , __func__, ret); |
1287 | pm_runtime_put_noidle(dev: priv->dev); |
1288 | return ret; |
1289 | } |
1290 | |
1291 | ctucan_get_rec_tec(priv, bec); |
1292 | pm_runtime_put(dev: priv->dev); |
1293 | |
1294 | return 0; |
1295 | } |
1296 | |
1297 | static const struct net_device_ops ctucan_netdev_ops = { |
1298 | .ndo_open = ctucan_open, |
1299 | .ndo_stop = ctucan_close, |
1300 | .ndo_start_xmit = ctucan_start_xmit, |
1301 | .ndo_change_mtu = can_change_mtu, |
1302 | }; |
1303 | |
1304 | static const struct ethtool_ops ctucan_ethtool_ops = { |
1305 | .get_ts_info = ethtool_op_get_ts_info, |
1306 | }; |
1307 | |
1308 | int ctucan_suspend(struct device *dev) |
1309 | { |
1310 | struct net_device *ndev = dev_get_drvdata(dev); |
1311 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
1312 | |
1313 | if (netif_running(dev: ndev)) { |
1314 | netif_stop_queue(dev: ndev); |
1315 | netif_device_detach(dev: ndev); |
1316 | } |
1317 | |
1318 | priv->can.state = CAN_STATE_SLEEPING; |
1319 | |
1320 | return 0; |
1321 | } |
1322 | EXPORT_SYMBOL(ctucan_suspend); |
1323 | |
1324 | int ctucan_resume(struct device *dev) |
1325 | { |
1326 | struct net_device *ndev = dev_get_drvdata(dev); |
1327 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
1328 | |
1329 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
1330 | |
1331 | if (netif_running(dev: ndev)) { |
1332 | netif_device_attach(dev: ndev); |
1333 | netif_start_queue(dev: ndev); |
1334 | } |
1335 | |
1336 | return 0; |
1337 | } |
1338 | EXPORT_SYMBOL(ctucan_resume); |
1339 | |
1340 | int ctucan_probe_common(struct device *dev, void __iomem *addr, int irq, unsigned int ntxbufs, |
1341 | unsigned long can_clk_rate, int pm_enable_call, |
1342 | void (*set_drvdata_fnc)(struct device *dev, struct net_device *ndev)) |
1343 | { |
1344 | struct ctucan_priv *priv; |
1345 | struct net_device *ndev; |
1346 | int ret; |
1347 | |
1348 | /* Create a CAN device instance */ |
1349 | ndev = alloc_candev(sizeof(struct ctucan_priv), ntxbufs); |
1350 | if (!ndev) |
1351 | return -ENOMEM; |
1352 | |
1353 | priv = netdev_priv(dev: ndev); |
1354 | spin_lock_init(&priv->tx_lock); |
1355 | INIT_LIST_HEAD(list: &priv->peers_on_pdev); |
1356 | priv->ntxbufs = ntxbufs; |
1357 | priv->dev = dev; |
1358 | priv->can.bittiming_const = &ctu_can_fd_bit_timing_max; |
1359 | priv->can.data_bittiming_const = &ctu_can_fd_bit_timing_data_max; |
1360 | priv->can.do_set_mode = ctucan_do_set_mode; |
1361 | |
1362 | /* Needed for timing adjustment to be performed as soon as possible */ |
1363 | priv->can.do_set_bittiming = ctucan_set_bittiming; |
1364 | priv->can.do_set_data_bittiming = ctucan_set_data_bittiming; |
1365 | |
1366 | priv->can.do_get_berr_counter = ctucan_get_berr_counter; |
1367 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
1368 | | CAN_CTRLMODE_LISTENONLY |
1369 | | CAN_CTRLMODE_FD |
1370 | | CAN_CTRLMODE_PRESUME_ACK |
1371 | | CAN_CTRLMODE_BERR_REPORTING |
1372 | | CAN_CTRLMODE_FD_NON_ISO |
1373 | | CAN_CTRLMODE_ONE_SHOT; |
1374 | priv->mem_base = addr; |
1375 | |
1376 | /* Get IRQ for the device */ |
1377 | ndev->irq = irq; |
1378 | ndev->flags |= IFF_ECHO; /* We support local echo */ |
1379 | |
1380 | if (set_drvdata_fnc) |
1381 | set_drvdata_fnc(dev, ndev); |
1382 | SET_NETDEV_DEV(ndev, dev); |
1383 | ndev->netdev_ops = &ctucan_netdev_ops; |
1384 | ndev->ethtool_ops = &ctucan_ethtool_ops; |
1385 | |
1386 | /* Getting the can_clk info */ |
1387 | if (!can_clk_rate) { |
1388 | priv->can_clk = devm_clk_get(dev, NULL); |
1389 | if (IS_ERR(ptr: priv->can_clk)) { |
1390 | dev_err(dev, "Device clock not found.\n" ); |
1391 | ret = PTR_ERR(ptr: priv->can_clk); |
1392 | goto err_free; |
1393 | } |
1394 | can_clk_rate = clk_get_rate(clk: priv->can_clk); |
1395 | } |
1396 | |
1397 | priv->write_reg = ctucan_write32_le; |
1398 | priv->read_reg = ctucan_read32_le; |
1399 | |
1400 | if (pm_enable_call) |
1401 | pm_runtime_enable(dev); |
1402 | ret = pm_runtime_get_sync(dev); |
1403 | if (ret < 0) { |
1404 | netdev_err(dev: ndev, format: "%s: pm_runtime_get failed(%d)\n" , |
1405 | __func__, ret); |
1406 | pm_runtime_put_noidle(dev: priv->dev); |
1407 | goto err_pmdisable; |
1408 | } |
1409 | |
1410 | /* Check for big-endianity and set according IO-accessors */ |
1411 | if ((ctucan_read32(priv, reg: CTUCANFD_DEVICE_ID) & 0xFFFF) != CTUCANFD_ID) { |
1412 | priv->write_reg = ctucan_write32_be; |
1413 | priv->read_reg = ctucan_read32_be; |
1414 | if ((ctucan_read32(priv, reg: CTUCANFD_DEVICE_ID) & 0xFFFF) != CTUCANFD_ID) { |
1415 | netdev_err(dev: ndev, format: "CTU_CAN_FD signature not found\n" ); |
1416 | ret = -ENODEV; |
1417 | goto err_deviceoff; |
1418 | } |
1419 | } |
1420 | |
1421 | ret = ctucan_reset(ndev); |
1422 | if (ret < 0) |
1423 | goto err_deviceoff; |
1424 | |
1425 | priv->can.clock.freq = can_clk_rate; |
1426 | |
1427 | netif_napi_add(dev: ndev, napi: &priv->napi, poll: ctucan_rx_poll); |
1428 | |
1429 | ret = register_candev(dev: ndev); |
1430 | if (ret) { |
1431 | dev_err(dev, "fail to register failed (err=%d)\n" , ret); |
1432 | goto err_deviceoff; |
1433 | } |
1434 | |
1435 | pm_runtime_put(dev); |
1436 | |
1437 | netdev_dbg(ndev, "mem_base=0x%p irq=%d clock=%d, no. of txt buffers:%d\n" , |
1438 | priv->mem_base, ndev->irq, priv->can.clock.freq, priv->ntxbufs); |
1439 | |
1440 | return 0; |
1441 | |
1442 | err_deviceoff: |
1443 | pm_runtime_put(dev: priv->dev); |
1444 | err_pmdisable: |
1445 | if (pm_enable_call) |
1446 | pm_runtime_disable(dev); |
1447 | err_free: |
1448 | list_del_init(entry: &priv->peers_on_pdev); |
1449 | free_candev(dev: ndev); |
1450 | return ret; |
1451 | } |
1452 | EXPORT_SYMBOL(ctucan_probe_common); |
1453 | |
1454 | MODULE_LICENSE("GPL" ); |
1455 | MODULE_AUTHOR("Martin Jerabek <martin.jerabek01@gmail.com>" ); |
1456 | MODULE_AUTHOR("Pavel Pisa <pisa@cmp.felk.cvut.cz>" ); |
1457 | MODULE_AUTHOR("Ondrej Ille <ondrej.ille@gmail.com>" ); |
1458 | MODULE_DESCRIPTION("CTU CAN FD interface" ); |
1459 | |