1 /*
2  * Copyright (c) 2019 Vestas Wind Systems A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /* Base driver compatible */
8 #define DT_DRV_COMPAT nxp_flexcan
9 
10 /* CAN-FD extension compatible */
11 #define FLEXCAN_FD_DRV_COMPAT nxp_flexcan_fd
12 
13 #include <zephyr/kernel.h>
14 #include <zephyr/sys/atomic.h>
15 #include <zephyr/drivers/can.h>
16 #include <zephyr/drivers/can/transceiver.h>
17 #include <zephyr/drivers/clock_control.h>
18 #include <zephyr/device.h>
19 #include <zephyr/sys/byteorder.h>
20 #include <fsl_flexcan.h>
21 #include <zephyr/logging/log.h>
22 #include <zephyr/irq.h>
23 #include <zephyr/drivers/pinctrl.h>
24 
25 LOG_MODULE_REGISTER(can_mcux_flexcan, CONFIG_CAN_LOG_LEVEL);
26 
27 #define SP_IS_SET(inst) DT_INST_NODE_HAS_PROP(inst, sample_point) ||
28 
29 /* Macro to exclude the sample point algorithm from compilation if not used
30  * Without the macro, the algorithm would always waste ROM
31  */
32 #define USE_SP_ALGO (DT_INST_FOREACH_STATUS_OKAY(SP_IS_SET) 0)
33 
34 #define SP_AND_TIMING_NOT_SET(inst) \
35 	(!DT_INST_NODE_HAS_PROP(inst, sample_point) && \
36 	!(DT_INST_NODE_HAS_PROP(inst, prop_seg) && \
37 	DT_INST_NODE_HAS_PROP(inst, phase_seg1) && \
38 	DT_INST_NODE_HAS_PROP(inst, phase_seg2))) ||
39 
40 #if DT_INST_FOREACH_STATUS_OKAY(SP_AND_TIMING_NOT_SET) 0
41 #error You must either set a sampling-point or timings (phase-seg* and prop-seg)
42 #endif
43 
44 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
45 	(defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
46 /* the first valid MB should be occupied by ERRATA 5461 or 5829. */
47 #define RX_START_IDX 1
48 #else
49 #define RX_START_IDX 0
50 #endif
51 
52 /* The maximum number of message buffers for concurrent active instances */
53 #ifdef CONFIG_CAN_MAX_MB
54 #define MCUX_FLEXCAN_MAX_MB CONFIG_CAN_MAX_MB
55 #else
56 #define MCUX_FLEXCAN_MAX_MB FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0)
57 #endif
58 
59 /*
60  * RX message buffers (filters) will take up the first N message
61  * buffers. The rest are available for TX use.
62  */
63 #define MCUX_FLEXCAN_MAX_RX (CONFIG_CAN_MAX_FILTER + RX_START_IDX)
64 #define MCUX_FLEXCAN_MAX_TX (MCUX_FLEXCAN_MAX_MB - MCUX_FLEXCAN_MAX_RX)
65 
66 /*
67  * Convert from RX message buffer index to allocated filter ID and
68  * vice versa.
69  */
70 #define RX_MBIDX_TO_ALLOC_IDX(x) (x)
71 #define ALLOC_IDX_TO_RXMB_IDX(x) (x)
72 
73 /*
74  * Convert from TX message buffer index to allocated TX ID and vice
75  * versa.
76  */
77 #define TX_MBIDX_TO_ALLOC_IDX(x) (x - MCUX_FLEXCAN_MAX_RX)
78 #define ALLOC_IDX_TO_TXMB_IDX(x) (x + MCUX_FLEXCAN_MAX_RX)
79 
80 /* Convert from back from FLEXCAN IDs to Zephyr CAN IDs. */
81 #define FLEXCAN_ID_TO_CAN_ID_STD(id) \
82 	((uint32_t)((((uint32_t)(id)) & CAN_ID_STD_MASK) >> CAN_ID_STD_SHIFT))
83 #define FLEXCAN_ID_TO_CAN_ID_EXT(id) \
84 	((uint32_t)((((uint32_t)(id)) & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK)) \
85 	>> CAN_ID_EXT_SHIFT))
86 
87 struct mcux_flexcan_config {
88 	CAN_Type *base;
89 	const struct device *clock_dev;
90 	clock_control_subsys_t clock_subsys;
91 	int clk_source;
92 	uint32_t bitrate;
93 	uint32_t sample_point;
94 	uint32_t sjw;
95 	uint32_t prop_seg;
96 	uint32_t phase_seg1;
97 	uint32_t phase_seg2;
98 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
99 	bool flexcan_fd;
100 	uint32_t bitrate_data;
101 	uint32_t sample_point_data;
102 	uint32_t sjw_data;
103 	uint32_t prop_seg_data;
104 	uint32_t phase_seg1_data;
105 	uint32_t phase_seg2_data;
106 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
107 	void (*irq_config_func)(const struct device *dev);
108 	void (*irq_enable_func)(void);
109 	void (*irq_disable_func)(void);
110 	const struct device *phy;
111 	uint32_t max_bitrate;
112 	const struct pinctrl_dev_config *pincfg;
113 };
114 
115 struct mcux_flexcan_rx_callback {
116 	flexcan_rx_mb_config_t mb_config;
117 	union {
118 		flexcan_frame_t classic;
119 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
120 		flexcan_fd_frame_t fd;
121 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
122 	} frame;
123 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
124 	bool fdf;
125 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
126 	can_rx_callback_t function;
127 	void *arg;
128 };
129 
130 struct mcux_flexcan_tx_callback {
131 	can_tx_callback_t function;
132 	void *arg;
133 };
134 
135 struct mcux_flexcan_data {
136 	const struct device *dev;
137 	flexcan_handle_t handle;
138 
139 	ATOMIC_DEFINE(rx_allocs, MCUX_FLEXCAN_MAX_RX);
140 	struct k_mutex rx_mutex;
141 	struct mcux_flexcan_rx_callback rx_cbs[MCUX_FLEXCAN_MAX_RX];
142 
143 	ATOMIC_DEFINE(tx_allocs, MCUX_FLEXCAN_MAX_TX);
144 	struct k_sem tx_allocs_sem;
145 	struct k_mutex tx_mutex;
146 	struct mcux_flexcan_tx_callback tx_cbs[MCUX_FLEXCAN_MAX_TX];
147 	enum can_state state;
148 	can_state_change_callback_t state_change_cb;
149 	void *state_change_cb_data;
150 	struct can_timing timing;
151 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
152 	struct can_timing timing_data;
153 	bool fd_mode;
154 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
155 	bool started;
156 };
157 
mcux_flexcan_get_core_clock(const struct device * dev,uint32_t * rate)158 static int mcux_flexcan_get_core_clock(const struct device *dev, uint32_t *rate)
159 {
160 	const struct mcux_flexcan_config *config = dev->config;
161 
162 	return clock_control_get_rate(config->clock_dev, config->clock_subsys, rate);
163 }
164 
mcux_flexcan_get_max_filters(const struct device * dev,bool ide)165 static int mcux_flexcan_get_max_filters(const struct device *dev, bool ide)
166 {
167 	ARG_UNUSED(ide);
168 
169 	return CONFIG_CAN_MAX_FILTER;
170 }
171 
mcux_flexcan_get_max_bitrate(const struct device * dev,uint32_t * max_bitrate)172 static int mcux_flexcan_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate)
173 {
174 	const struct mcux_flexcan_config *config = dev->config;
175 
176 	*max_bitrate = config->max_bitrate;
177 
178 	return 0;
179 }
180 
mcux_flexcan_set_timing(const struct device * dev,const struct can_timing * timing)181 static int mcux_flexcan_set_timing(const struct device *dev,
182 				   const struct can_timing *timing)
183 {
184 	struct mcux_flexcan_data *data = dev->data;
185 
186 	if (!timing) {
187 		return -EINVAL;
188 	}
189 
190 	if (data->started) {
191 		return -EBUSY;
192 	}
193 
194 	data->timing = *timing;
195 
196 	return 0;
197 }
198 
199 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
mcux_flexcan_set_timing_data(const struct device * dev,const struct can_timing * timing_data)200 static int mcux_flexcan_set_timing_data(const struct device *dev,
201 					const struct can_timing *timing_data)
202 {
203 	struct mcux_flexcan_data *data = dev->data;
204 
205 	if (!timing_data) {
206 		return -EINVAL;
207 	}
208 
209 	if (data->started) {
210 		return -EBUSY;
211 	}
212 
213 	data->timing_data = *timing_data;
214 
215 	return 0;
216 }
217 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
218 
mcux_flexcan_get_capabilities(const struct device * dev,can_mode_t * cap)219 static int mcux_flexcan_get_capabilities(const struct device *dev, can_mode_t *cap)
220 {
221 	__maybe_unused const struct mcux_flexcan_config *config = dev->config;
222 
223 	*cap = CAN_MODE_NORMAL | CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY | CAN_MODE_3_SAMPLES;
224 
225 	if (UTIL_AND(IS_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD), config->flexcan_fd)) {
226 		*cap |= CAN_MODE_FD;
227 	}
228 
229 	return 0;
230 }
231 
mcux_flexcan_mb_start(const struct device * dev,int alloc)232 static status_t mcux_flexcan_mb_start(const struct device *dev, int alloc)
233 {
234 	const struct mcux_flexcan_config *config = dev->config;
235 	struct mcux_flexcan_data *data = dev->data;
236 	flexcan_mb_transfer_t xfer;
237 	status_t status;
238 
239 	__ASSERT_NO_MSG(alloc >= 0 && alloc < ARRAY_SIZE(data->rx_cbs));
240 
241 	xfer.mbIdx = ALLOC_IDX_TO_RXMB_IDX(alloc);
242 
243 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
244 	if (data->fd_mode) {
245 		xfer.framefd = &data->rx_cbs[alloc].frame.fd;
246 		FLEXCAN_SetFDRxMbConfig(config->base, ALLOC_IDX_TO_RXMB_IDX(alloc),
247 					&data->rx_cbs[alloc].mb_config, true);
248 		status = FLEXCAN_TransferFDReceiveNonBlocking(config->base, &data->handle, &xfer);
249 	} else {
250 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
251 		xfer.frame = &data->rx_cbs[alloc].frame.classic;
252 		FLEXCAN_SetRxMbConfig(config->base, ALLOC_IDX_TO_RXMB_IDX(alloc),
253 				      &data->rx_cbs[alloc].mb_config, true);
254 		status = FLEXCAN_TransferReceiveNonBlocking(config->base, &data->handle, &xfer);
255 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
256 	}
257 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
258 
259 	return status;
260 }
261 
mcux_flexcan_mb_stop(const struct device * dev,int alloc)262 static void mcux_flexcan_mb_stop(const struct device *dev, int alloc)
263 {
264 	const struct mcux_flexcan_config *config = dev->config;
265 	struct mcux_flexcan_data *data = dev->data;
266 
267 	__ASSERT_NO_MSG(alloc >= 0 && alloc < ARRAY_SIZE(data->rx_cbs));
268 
269 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
270 	if (data->fd_mode) {
271 		FLEXCAN_TransferFDAbortReceive(config->base, &data->handle,
272 					       ALLOC_IDX_TO_RXMB_IDX(alloc));
273 		FLEXCAN_SetFDRxMbConfig(config->base, ALLOC_IDX_TO_RXMB_IDX(alloc),
274 					NULL, false);
275 		} else {
276 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
277 			FLEXCAN_TransferAbortReceive(config->base, &data->handle,
278 						     ALLOC_IDX_TO_RXMB_IDX(alloc));
279 			FLEXCAN_SetRxMbConfig(config->base, ALLOC_IDX_TO_RXMB_IDX(alloc),
280 					      NULL, false);
281 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
282 		}
283 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
284 }
285 
mcux_flexcan_start(const struct device * dev)286 static int mcux_flexcan_start(const struct device *dev)
287 {
288 	const struct mcux_flexcan_config *config = dev->config;
289 	struct mcux_flexcan_data *data = dev->data;
290 	flexcan_timing_config_t timing;
291 	int err;
292 
293 	if (data->started) {
294 		return -EALREADY;
295 	}
296 
297 	if (config->phy != NULL) {
298 		err = can_transceiver_enable(config->phy);
299 		if (err != 0) {
300 			LOG_ERR("failed to enable CAN transceiver (err %d)", err);
301 			return err;
302 		}
303 	}
304 
305 	/* Reset statistics and clear error counters */
306 	CAN_STATS_RESET(dev);
307 	config->base->ECR &= ~(CAN_ECR_TXERRCNT_MASK | CAN_ECR_RXERRCNT_MASK);
308 
309 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
310 	status_t status;
311 	int alloc;
312 
313 	if (config->flexcan_fd) {
314 		/* Re-add all RX filters using current mode */
315 		k_mutex_lock(&data->rx_mutex, K_FOREVER);
316 
317 		for (alloc = RX_START_IDX; alloc < MCUX_FLEXCAN_MAX_RX; alloc++) {
318 			if (atomic_test_bit(data->rx_allocs, alloc)) {
319 				status = mcux_flexcan_mb_start(dev, alloc);
320 				if (status != kStatus_Success) {
321 					LOG_ERR("Failed to re-add rx filter id %d (err = %d)",
322 						alloc, status);
323 					k_mutex_unlock(&data->rx_mutex);
324 					return -EIO;
325 				}
326 			}
327 		}
328 
329 		k_mutex_unlock(&data->rx_mutex);
330 	}
331 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
332 
333 	/* Delay this until start since setting the timing automatically exits freeze mode */
334 	timing.preDivider = data->timing.prescaler - 1U;
335 	timing.rJumpwidth = data->timing.sjw - 1U;
336 	timing.phaseSeg1 = data->timing.phase_seg1 - 1U;
337 	timing.phaseSeg2 = data->timing.phase_seg2 - 1U;
338 	timing.propSeg = data->timing.prop_seg - 1U;
339 	FLEXCAN_SetTimingConfig(config->base, &timing);
340 
341 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
342 	if (config->flexcan_fd) {
343 		timing.fpreDivider = data->timing_data.prescaler - 1U;
344 		timing.frJumpwidth = data->timing_data.sjw - 1U;
345 		timing.fphaseSeg1 = data->timing_data.phase_seg1 - 1U;
346 		timing.fphaseSeg2 = data->timing_data.phase_seg2 - 1U;
347 		timing.fpropSeg = data->timing_data.prop_seg;
348 		FLEXCAN_SetFDTimingConfig(config->base, &timing);
349 	}
350 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
351 
352 	data->started = true;
353 
354 	return 0;
355 }
356 
mcux_flexcan_stop(const struct device * dev)357 static int mcux_flexcan_stop(const struct device *dev)
358 {
359 	const struct mcux_flexcan_config *config = dev->config;
360 	struct mcux_flexcan_data *data = dev->data;
361 	can_tx_callback_t function;
362 	void *arg;
363 	int alloc;
364 	int err;
365 
366 	if (!data->started) {
367 		return -EALREADY;
368 	}
369 
370 	data->started = false;
371 
372 	/* Abort any pending TX frames before entering freeze mode */
373 	for (alloc = 0; alloc < MCUX_FLEXCAN_MAX_TX; alloc++) {
374 		function = data->tx_cbs[alloc].function;
375 		arg = data->tx_cbs[alloc].arg;
376 
377 		if (atomic_test_and_clear_bit(data->tx_allocs, alloc)) {
378 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
379 			if (data->fd_mode) {
380 				FLEXCAN_TransferFDAbortSend(config->base, &data->handle,
381 							    ALLOC_IDX_TO_TXMB_IDX(alloc));
382 			} else {
383 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
384 				FLEXCAN_TransferAbortSend(config->base, &data->handle,
385 							  ALLOC_IDX_TO_TXMB_IDX(alloc));
386 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
387 			}
388 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
389 
390 			function(dev, -ENETDOWN, arg);
391 			k_sem_give(&data->tx_allocs_sem);
392 		}
393 	}
394 
395 	FLEXCAN_EnterFreezeMode(config->base);
396 
397 	if (UTIL_AND(IS_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD), config->flexcan_fd)) {
398 		/*
399 		 * Remove all RX filters and re-add them in start() since the mode may change
400 		 * between stop()/start().
401 		 */
402 		k_mutex_lock(&data->rx_mutex, K_FOREVER);
403 
404 		for (alloc = RX_START_IDX; alloc < MCUX_FLEXCAN_MAX_RX; alloc++) {
405 			if (atomic_test_bit(data->rx_allocs, alloc)) {
406 				mcux_flexcan_mb_stop(dev, alloc);
407 			}
408 		}
409 
410 		k_mutex_unlock(&data->rx_mutex);
411 	}
412 
413 	if (config->phy != NULL) {
414 		err = can_transceiver_disable(config->phy);
415 		if (err != 0) {
416 			LOG_ERR("failed to disable CAN transceiver (err %d)", err);
417 			return err;
418 		}
419 	}
420 
421 	return 0;
422 }
423 
mcux_flexcan_set_mode(const struct device * dev,can_mode_t mode)424 static int mcux_flexcan_set_mode(const struct device *dev, can_mode_t mode)
425 {
426 	can_mode_t supported = CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY | CAN_MODE_3_SAMPLES;
427 	const struct mcux_flexcan_config *config = dev->config;
428 	struct mcux_flexcan_data *data = dev->data;
429 	uint32_t ctrl1;
430 	uint32_t mcr;
431 
432 	if (data->started) {
433 		return -EBUSY;
434 	}
435 
436 	if (UTIL_AND(IS_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD), config->flexcan_fd)) {
437 		supported |= CAN_MODE_FD;
438 	}
439 
440 	if ((mode & ~(supported)) != 0) {
441 		LOG_ERR("unsupported mode: 0x%08x", mode);
442 		return -ENOTSUP;
443 	}
444 
445 	if ((mode & CAN_MODE_FD) != 0 && (mode & CAN_MODE_3_SAMPLES) != 0) {
446 		LOG_ERR("triple samling is not supported in CAN-FD mode");
447 		return -ENOTSUP;
448 	}
449 
450 	ctrl1 = config->base->CTRL1;
451 	mcr = config->base->MCR;
452 
453 	if ((mode & CAN_MODE_LOOPBACK) != 0) {
454 		/* Enable loopback and self-reception */
455 		ctrl1 |= CAN_CTRL1_LPB_MASK;
456 		mcr &= ~(CAN_MCR_SRXDIS_MASK);
457 	} else {
458 		/* Disable loopback and self-reception */
459 		ctrl1 &= ~(CAN_CTRL1_LPB_MASK);
460 		mcr |= CAN_MCR_SRXDIS_MASK;
461 	}
462 
463 	if ((mode & CAN_MODE_LISTENONLY) != 0) {
464 		/* Enable listen-only mode */
465 		ctrl1 |= CAN_CTRL1_LOM_MASK;
466 	} else {
467 		/* Disable listen-only mode */
468 		ctrl1 &= ~(CAN_CTRL1_LOM_MASK);
469 	}
470 
471 	if ((mode & CAN_MODE_3_SAMPLES) != 0) {
472 		/* Enable triple sampling mode */
473 		ctrl1 |= CAN_CTRL1_SMP_MASK;
474 	} else {
475 		/* Disable triple sampling mode */
476 		ctrl1 &= ~(CAN_CTRL1_SMP_MASK);
477 	}
478 
479 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
480 	if (config->flexcan_fd) {
481 		if ((mode & CAN_MODE_FD) != 0) {
482 			/* Enable CAN-FD mode */
483 			mcr |= CAN_MCR_FDEN_MASK;
484 			data->fd_mode = true;
485 
486 			/* Transceiver Delay Compensation must be disabled in loopback mode */
487 			if ((mode & CAN_MODE_LOOPBACK) != 0) {
488 				config->base->FDCTRL &= ~(CAN_FDCTRL_TDCEN_MASK);
489 			} else {
490 				config->base->FDCTRL |= CAN_FDCTRL_TDCEN_MASK;
491 			}
492 		} else {
493 			/* Disable CAN-FD mode */
494 			mcr &= ~(CAN_MCR_FDEN_MASK);
495 			data->fd_mode = false;
496 		}
497 	}
498 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
499 
500 	config->base->CTRL1 = ctrl1;
501 	config->base->MCR = mcr;
502 
503 	return 0;
504 }
505 
mcux_flexcan_from_can_frame(const struct can_frame * src,flexcan_frame_t * dest)506 static void mcux_flexcan_from_can_frame(const struct can_frame *src,
507 					flexcan_frame_t *dest)
508 {
509 	memset(dest, 0, sizeof(*dest));
510 
511 	if ((src->flags & CAN_FRAME_IDE) != 0) {
512 		dest->format = kFLEXCAN_FrameFormatExtend;
513 		dest->id = FLEXCAN_ID_EXT(src->id);
514 	} else {
515 		dest->format = kFLEXCAN_FrameFormatStandard;
516 		dest->id = FLEXCAN_ID_STD(src->id);
517 	}
518 
519 	if ((src->flags & CAN_FRAME_RTR) != 0) {
520 		dest->type = kFLEXCAN_FrameTypeRemote;
521 	} else {
522 		dest->type = kFLEXCAN_FrameTypeData;
523 		dest->dataWord0 = sys_cpu_to_be32(src->data_32[0]);
524 		dest->dataWord1 = sys_cpu_to_be32(src->data_32[1]);
525 	}
526 
527 	dest->length = src->dlc;
528 }
529 
mcux_flexcan_to_can_frame(const flexcan_frame_t * src,struct can_frame * dest)530 static void mcux_flexcan_to_can_frame(const flexcan_frame_t *src,
531 				      struct can_frame *dest)
532 {
533 	memset(dest, 0, sizeof(*dest));
534 
535 	if (src->format == kFLEXCAN_FrameFormatStandard) {
536 		dest->id = FLEXCAN_ID_TO_CAN_ID_STD(src->id);
537 	} else {
538 		dest->flags |= CAN_FRAME_IDE;
539 		dest->id = FLEXCAN_ID_TO_CAN_ID_EXT(src->id);
540 	}
541 
542 	if (src->type == kFLEXCAN_FrameTypeRemote) {
543 		dest->flags |= CAN_FRAME_RTR;
544 	} else {
545 		dest->data_32[0] = sys_be32_to_cpu(src->dataWord0);
546 		dest->data_32[1] = sys_be32_to_cpu(src->dataWord1);
547 	}
548 
549 	dest->dlc = src->length;
550 #ifdef CONFIG_CAN_RX_TIMESTAMP
551 	dest->timestamp = src->timestamp;
552 #endif /* CAN_RX_TIMESTAMP */
553 }
554 
555 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
mcux_flexcan_fd_from_can_frame(const struct can_frame * src,flexcan_fd_frame_t * dest)556 static void mcux_flexcan_fd_from_can_frame(const struct can_frame *src,
557 					   flexcan_fd_frame_t *dest)
558 {
559 	int i;
560 
561 	memset(dest, 0, sizeof(*dest));
562 
563 	if ((src->flags & CAN_FRAME_IDE) != 0) {
564 		dest->format = kFLEXCAN_FrameFormatExtend;
565 		dest->id = FLEXCAN_ID_EXT(src->id);
566 	} else {
567 		dest->format = kFLEXCAN_FrameFormatStandard;
568 		dest->id = FLEXCAN_ID_STD(src->id);
569 	}
570 
571 	if ((src->flags & CAN_FRAME_RTR) != 0) {
572 		dest->type = kFLEXCAN_FrameTypeRemote;
573 	} else {
574 		dest->type = kFLEXCAN_FrameTypeData;
575 
576 		for (i = 0; i < ARRAY_SIZE(dest->dataWord); i++) {
577 			dest->dataWord[i] = sys_cpu_to_be32(src->data_32[i]);
578 		}
579 	}
580 
581 	if ((src->flags & CAN_FRAME_FDF) != 0) {
582 		dest->edl = 1;
583 	}
584 
585 	if ((src->flags & CAN_FRAME_BRS) != 0) {
586 		dest->brs = 1;
587 	}
588 
589 	dest->length = src->dlc;
590 }
591 
mcux_flexcan_fd_to_can_frame(const flexcan_fd_frame_t * src,struct can_frame * dest)592 static void mcux_flexcan_fd_to_can_frame(const flexcan_fd_frame_t *src,
593 					 struct can_frame *dest)
594 {
595 	int i;
596 
597 	memset(dest, 0, sizeof(*dest));
598 
599 	if (src->format == kFLEXCAN_FrameFormatStandard) {
600 		dest->id = FLEXCAN_ID_TO_CAN_ID_STD(src->id);
601 	} else {
602 		dest->flags |= CAN_FRAME_IDE;
603 		dest->id = FLEXCAN_ID_TO_CAN_ID_EXT(src->id);
604 	}
605 
606 	if (src->type == kFLEXCAN_FrameTypeRemote) {
607 		dest->flags |= CAN_FRAME_RTR;
608 	} else {
609 		for (i = 0; i < ARRAY_SIZE(dest->data_32); i++) {
610 			dest->data_32[i] = sys_be32_to_cpu(src->dataWord[i]);
611 		}
612 	}
613 
614 	if (src->edl != 0) {
615 		dest->flags |= CAN_FRAME_FDF;
616 	}
617 
618 	if (src->brs != 0) {
619 		dest->flags |= CAN_FRAME_BRS;
620 	}
621 
622 	if (src->esi != 0) {
623 		dest->flags |= CAN_FRAME_ESI;
624 	}
625 
626 	dest->dlc = src->length;
627 
628 #ifdef CONFIG_CAN_RX_TIMESTAMP
629 	dest->timestamp = src->timestamp;
630 #endif /* CAN_RX_TIMESTAMP */
631 }
632 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
633 
mcux_flexcan_can_filter_to_mbconfig(const struct can_filter * src,flexcan_rx_mb_config_t * dest,uint32_t * mask)634 static void mcux_flexcan_can_filter_to_mbconfig(const struct can_filter *src,
635 						flexcan_rx_mb_config_t *dest,
636 						uint32_t *mask)
637 {
638 	static const uint32_t ide_mask = 1U;
639 	uint32_t rtr_mask = (src->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
640 		(CAN_FILTER_DATA | CAN_FILTER_RTR) ? 1U : 0U;
641 
642 	if ((src->flags & CAN_FILTER_IDE) != 0) {
643 		dest->format = kFLEXCAN_FrameFormatExtend;
644 		dest->id = FLEXCAN_ID_EXT(src->id);
645 		*mask = FLEXCAN_RX_MB_EXT_MASK(src->mask, rtr_mask, ide_mask);
646 	} else {
647 		dest->format = kFLEXCAN_FrameFormatStandard;
648 		dest->id = FLEXCAN_ID_STD(src->id);
649 		*mask = FLEXCAN_RX_MB_STD_MASK(src->mask, rtr_mask, ide_mask);
650 	}
651 
652 	if ((src->flags & CAN_FILTER_RTR) != 0) {
653 		dest->type = kFLEXCAN_FrameTypeRemote;
654 	} else {
655 		dest->type = kFLEXCAN_FrameTypeData;
656 	}
657 }
658 
mcux_flexcan_get_state(const struct device * dev,enum can_state * state,struct can_bus_err_cnt * err_cnt)659 static int mcux_flexcan_get_state(const struct device *dev, enum can_state *state,
660 				  struct can_bus_err_cnt *err_cnt)
661 {
662 	const struct mcux_flexcan_config *config = dev->config;
663 	struct mcux_flexcan_data *data = dev->data;
664 	uint64_t status_flags;
665 
666 	if (state != NULL) {
667 		if (!data->started) {
668 			*state = CAN_STATE_STOPPED;
669 		} else {
670 			status_flags = FLEXCAN_GetStatusFlags(config->base);
671 
672 			if ((status_flags & CAN_ESR1_FLTCONF(2)) != 0U) {
673 				*state = CAN_STATE_BUS_OFF;
674 			} else if ((status_flags & CAN_ESR1_FLTCONF(1)) != 0U) {
675 				*state = CAN_STATE_ERROR_PASSIVE;
676 			} else if ((status_flags &
677 				(kFLEXCAN_TxErrorWarningFlag | kFLEXCAN_RxErrorWarningFlag)) != 0) {
678 				*state = CAN_STATE_ERROR_WARNING;
679 			} else {
680 				*state = CAN_STATE_ERROR_ACTIVE;
681 			}
682 		}
683 	}
684 
685 	if (err_cnt != NULL) {
686 		FLEXCAN_GetBusErrCount(config->base, &err_cnt->tx_err_cnt,
687 				       &err_cnt->rx_err_cnt);
688 	}
689 
690 	return 0;
691 }
692 
mcux_flexcan_send(const struct device * dev,const struct can_frame * frame,k_timeout_t timeout,can_tx_callback_t callback,void * user_data)693 static int mcux_flexcan_send(const struct device *dev,
694 			     const struct can_frame *frame,
695 			     k_timeout_t timeout,
696 			     can_tx_callback_t callback, void *user_data)
697 {
698 	const struct mcux_flexcan_config *config = dev->config;
699 	struct mcux_flexcan_data *data = dev->data;
700 	flexcan_mb_transfer_t xfer;
701 	enum can_state state;
702 	status_t status = kStatus_Fail;
703 	uint8_t max_dlc = CAN_MAX_DLC;
704 	int alloc;
705 
706 	__ASSERT_NO_MSG(callback != NULL);
707 
708 	if (UTIL_AND(IS_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD), data->fd_mode)) {
709 		if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR |
710 				      CAN_FRAME_FDF | CAN_FRAME_BRS)) != 0) {
711 			LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
712 			return -ENOTSUP;
713 		}
714 
715 		if ((frame->flags & CAN_FRAME_FDF) != 0) {
716 			max_dlc = CANFD_MAX_DLC;
717 		}
718 	} else {
719 		if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
720 			LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
721 			return -ENOTSUP;
722 		}
723 	}
724 
725 	if (frame->dlc > max_dlc) {
726 		LOG_ERR("DLC of %d exceeds maximum (%d)", frame->dlc, max_dlc);
727 		return -EINVAL;
728 	}
729 
730 	if (!data->started) {
731 		return -ENETDOWN;
732 	}
733 
734 	(void)mcux_flexcan_get_state(dev, &state, NULL);
735 	if (state == CAN_STATE_BUS_OFF) {
736 		LOG_DBG("Transmit failed, bus-off");
737 		return -ENETUNREACH;
738 	}
739 
740 	if (k_sem_take(&data->tx_allocs_sem, timeout) != 0) {
741 		return -EAGAIN;
742 	}
743 
744 	for (alloc = 0; alloc < MCUX_FLEXCAN_MAX_TX; alloc++) {
745 		if (!atomic_test_and_set_bit(data->tx_allocs, alloc)) {
746 			break;
747 		}
748 	}
749 
750 	data->tx_cbs[alloc].function = callback;
751 	data->tx_cbs[alloc].arg = user_data;
752 	xfer.mbIdx = ALLOC_IDX_TO_TXMB_IDX(alloc);
753 
754 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
755 	if (data->fd_mode) {
756 		FLEXCAN_SetFDTxMbConfig(config->base, xfer.mbIdx, true);
757 	} else {
758 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
759 		FLEXCAN_SetTxMbConfig(config->base, xfer.mbIdx, true);
760 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
761 	}
762 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
763 
764 	k_mutex_lock(&data->tx_mutex, K_FOREVER);
765 	config->irq_disable_func();
766 
767 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
768 	if (data->fd_mode) {
769 		flexcan_fd_frame_t flexcan_frame;
770 
771 		mcux_flexcan_fd_from_can_frame(frame, &flexcan_frame);
772 		xfer.framefd = &flexcan_frame;
773 		status = FLEXCAN_TransferFDSendNonBlocking(config->base, &data->handle, &xfer);
774 	} else {
775 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
776 		flexcan_frame_t flexcan_frame;
777 
778 		mcux_flexcan_from_can_frame(frame, &flexcan_frame);
779 		xfer.frame = &flexcan_frame;
780 		status = FLEXCAN_TransferSendNonBlocking(config->base, &data->handle, &xfer);
781 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
782 	}
783 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
784 
785 	config->irq_enable_func();
786 	k_mutex_unlock(&data->tx_mutex);
787 	if (status != kStatus_Success) {
788 		return -EIO;
789 	}
790 
791 	return 0;
792 }
793 
mcux_flexcan_add_rx_filter(const struct device * dev,can_rx_callback_t callback,void * user_data,const struct can_filter * filter)794 static int mcux_flexcan_add_rx_filter(const struct device *dev,
795 				      can_rx_callback_t callback,
796 				      void *user_data,
797 				      const struct can_filter *filter)
798 {
799 	uint8_t supported = CAN_FILTER_IDE | CAN_FILTER_DATA | CAN_FILTER_RTR;
800 	const struct mcux_flexcan_config *config = dev->config;
801 	struct mcux_flexcan_data *data = dev->data;
802 	status_t status;
803 	uint32_t mask;
804 	int alloc = -ENOSPC;
805 	int i;
806 
807 	__ASSERT_NO_MSG(callback);
808 
809 	if (UTIL_AND(IS_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD), config->flexcan_fd)) {
810 		supported |= CAN_FILTER_FDF;
811 	}
812 
813 	if ((filter->flags & ~(supported)) != 0) {
814 		LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
815 		return -ENOTSUP;
816 	}
817 
818 	k_mutex_lock(&data->rx_mutex, K_FOREVER);
819 
820 	/* Find and allocate RX message buffer */
821 	for (i = RX_START_IDX; i < MCUX_FLEXCAN_MAX_RX; i++) {
822 		if (!atomic_test_and_set_bit(data->rx_allocs, i)) {
823 			alloc = i;
824 			break;
825 		}
826 	}
827 
828 	if (alloc == -ENOSPC) {
829 		goto unlock;
830 	}
831 
832 	mcux_flexcan_can_filter_to_mbconfig(filter, &data->rx_cbs[alloc].mb_config,
833 					    &mask);
834 
835 	data->rx_cbs[alloc].arg = user_data;
836 	data->rx_cbs[alloc].function = callback;
837 
838 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
839 	/* FDF filtering not supported in hardware, must be handled in driver */
840 	data->rx_cbs[alloc].fdf = (filter->flags & CAN_FILTER_FDF) != 0;
841 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
842 
843 	/* The indidual RX mask registers can only be written in freeze mode */
844 	FLEXCAN_EnterFreezeMode(config->base);
845 	config->base->RXIMR[ALLOC_IDX_TO_RXMB_IDX(alloc)] = mask;
846 
847 	if (data->started) {
848 		FLEXCAN_ExitFreezeMode(config->base);
849 	}
850 
851 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
852 	/* Defer starting FlexCAN-FD MBs unless started */
853 	if (!config->flexcan_fd || data->started) {
854 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
855 		status = mcux_flexcan_mb_start(dev, alloc);
856 		if (status != kStatus_Success) {
857 			LOG_ERR("Failed to start rx for filter id %d (err = %d)",
858 				alloc, status);
859 			alloc = -ENOSPC;
860 		}
861 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
862 	}
863 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
864 
865 unlock:
866 	k_mutex_unlock(&data->rx_mutex);
867 
868 	return alloc;
869 }
870 
mcux_flexcan_set_state_change_callback(const struct device * dev,can_state_change_callback_t callback,void * user_data)871 static void mcux_flexcan_set_state_change_callback(const struct device *dev,
872 						   can_state_change_callback_t callback,
873 						   void *user_data)
874 {
875 	struct mcux_flexcan_data *data = dev->data;
876 
877 	data->state_change_cb = callback;
878 	data->state_change_cb_data = user_data;
879 }
880 
881 #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
mcux_flexcan_recover(const struct device * dev,k_timeout_t timeout)882 static int mcux_flexcan_recover(const struct device *dev, k_timeout_t timeout)
883 {
884 	const struct mcux_flexcan_config *config = dev->config;
885 	struct mcux_flexcan_data *data = dev->data;
886 	enum can_state state;
887 	uint64_t start_time;
888 	int ret = 0;
889 
890 	if (!data->started) {
891 		return -ENETDOWN;
892 	}
893 
894 	(void)mcux_flexcan_get_state(dev, &state, NULL);
895 	if (state != CAN_STATE_BUS_OFF) {
896 		return 0;
897 	}
898 
899 	start_time = k_uptime_ticks();
900 	config->base->CTRL1 &= ~CAN_CTRL1_BOFFREC_MASK;
901 
902 	if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
903 		(void)mcux_flexcan_get_state(dev, &state, NULL);
904 
905 		while (state == CAN_STATE_BUS_OFF) {
906 			if (!K_TIMEOUT_EQ(timeout, K_FOREVER) &&
907 			    k_uptime_ticks() - start_time >= timeout.ticks) {
908 				ret = -EAGAIN;
909 			}
910 
911 			(void)mcux_flexcan_get_state(dev, &state, NULL);
912 		}
913 	}
914 
915 	config->base->CTRL1 |= CAN_CTRL1_BOFFREC_MASK;
916 
917 	return ret;
918 }
919 #endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
920 
mcux_flexcan_remove_rx_filter(const struct device * dev,int filter_id)921 static void mcux_flexcan_remove_rx_filter(const struct device *dev, int filter_id)
922 {
923 	struct mcux_flexcan_data *data = dev->data;
924 
925 	if (filter_id >= MCUX_FLEXCAN_MAX_RX) {
926 		LOG_ERR("Detach: Filter id >= MAX_RX (%d >= %d)", filter_id,
927 			MCUX_FLEXCAN_MAX_RX);
928 		return;
929 	}
930 
931 	k_mutex_lock(&data->rx_mutex, K_FOREVER);
932 
933 	if (atomic_test_and_clear_bit(data->rx_allocs, filter_id)) {
934 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
935 		const struct mcux_flexcan_config *config = dev->config;
936 
937 		/* Stop FlexCAN-FD MBs unless already in stopped mode */
938 		if (!config->flexcan_fd || data->started) {
939 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
940 			mcux_flexcan_mb_stop(dev, filter_id);
941 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
942 		}
943 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
944 
945 		data->rx_cbs[filter_id].function = NULL;
946 		data->rx_cbs[filter_id].arg = NULL;
947 	} else {
948 		LOG_WRN("Filter ID %d already detached", filter_id);
949 	}
950 
951 	k_mutex_unlock(&data->rx_mutex);
952 }
953 
mcux_flexcan_transfer_error_status(const struct device * dev,uint64_t error)954 static inline void mcux_flexcan_transfer_error_status(const struct device *dev,
955 						      uint64_t error)
956 {
957 	const struct mcux_flexcan_config *config = dev->config;
958 	struct mcux_flexcan_data *data = dev->data;
959 	const can_state_change_callback_t cb = data->state_change_cb;
960 	void *cb_data = data->state_change_cb_data;
961 	can_tx_callback_t function;
962 	void *arg;
963 	int alloc;
964 	enum can_state state;
965 	struct can_bus_err_cnt err_cnt;
966 
967 	if ((error & kFLEXCAN_Bit0Error) != 0U) {
968 		CAN_STATS_BIT0_ERROR_INC(dev);
969 	}
970 
971 	if ((error & kFLEXCAN_Bit1Error) != 0U) {
972 		CAN_STATS_BIT1_ERROR_INC(dev);
973 	}
974 
975 	if ((error & kFLEXCAN_AckError) != 0U) {
976 		CAN_STATS_ACK_ERROR_INC(dev);
977 	}
978 
979 	if ((error & kFLEXCAN_StuffingError) != 0U) {
980 		CAN_STATS_STUFF_ERROR_INC(dev);
981 	}
982 
983 	if ((error & kFLEXCAN_FormError) != 0U) {
984 		CAN_STATS_FORM_ERROR_INC(dev);
985 	}
986 
987 	if ((error & kFLEXCAN_CrcError) != 0U) {
988 		CAN_STATS_CRC_ERROR_INC(dev);
989 	}
990 
991 	(void)mcux_flexcan_get_state(dev, &state, &err_cnt);
992 	if (data->state != state) {
993 		data->state = state;
994 
995 		if (cb != NULL) {
996 			cb(dev, state, err_cnt, cb_data);
997 		}
998 	}
999 
1000 	if (state == CAN_STATE_BUS_OFF) {
1001 		/* Abort any pending TX frames in case of bus-off */
1002 		for (alloc = 0; alloc < MCUX_FLEXCAN_MAX_TX; alloc++) {
1003 			/* Copy callback function and argument before clearing bit */
1004 			function = data->tx_cbs[alloc].function;
1005 			arg = data->tx_cbs[alloc].arg;
1006 
1007 			if (atomic_test_and_clear_bit(data->tx_allocs, alloc)) {
1008 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1009 				if (data->fd_mode) {
1010 					FLEXCAN_TransferFDAbortSend(config->base, &data->handle,
1011 								    ALLOC_IDX_TO_TXMB_IDX(alloc));
1012 				} else {
1013 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1014 					FLEXCAN_TransferAbortSend(config->base, &data->handle,
1015 								  ALLOC_IDX_TO_TXMB_IDX(alloc));
1016 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1017 				}
1018 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1019 
1020 				function(dev, -ENETUNREACH, arg);
1021 				k_sem_give(&data->tx_allocs_sem);
1022 			}
1023 		}
1024 	}
1025 }
1026 
mcux_flexcan_transfer_tx_idle(const struct device * dev,uint32_t mb)1027 static inline void mcux_flexcan_transfer_tx_idle(const struct device *dev,
1028 						 uint32_t mb)
1029 {
1030 	struct mcux_flexcan_data *data = dev->data;
1031 	can_tx_callback_t function;
1032 	void *arg;
1033 	int alloc;
1034 
1035 	alloc = TX_MBIDX_TO_ALLOC_IDX(mb);
1036 
1037 	/* Copy callback function and argument before clearing bit */
1038 	function = data->tx_cbs[alloc].function;
1039 	arg = data->tx_cbs[alloc].arg;
1040 
1041 	if (atomic_test_and_clear_bit(data->tx_allocs, alloc)) {
1042 		function(dev, 0, arg);
1043 		k_sem_give(&data->tx_allocs_sem);
1044 	}
1045 }
1046 
mcux_flexcan_transfer_rx_idle(const struct device * dev,uint32_t mb)1047 static inline void mcux_flexcan_transfer_rx_idle(const struct device *dev,
1048 						 uint32_t mb)
1049 {
1050 	const struct mcux_flexcan_config *config = dev->config;
1051 	struct mcux_flexcan_data *data = dev->data;
1052 	can_rx_callback_t function;
1053 	flexcan_mb_transfer_t xfer;
1054 	struct can_frame frame;
1055 	status_t status = kStatus_Fail;
1056 	void *arg;
1057 	int alloc;
1058 
1059 	alloc = RX_MBIDX_TO_ALLOC_IDX(mb);
1060 	function = data->rx_cbs[alloc].function;
1061 	arg = data->rx_cbs[alloc].arg;
1062 
1063 	if (atomic_test_bit(data->rx_allocs, alloc)) {
1064 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1065 		if (data->fd_mode) {
1066 			mcux_flexcan_fd_to_can_frame(&data->rx_cbs[alloc].frame.fd, &frame);
1067 		} else {
1068 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1069 			mcux_flexcan_to_can_frame(&data->rx_cbs[alloc].frame.classic, &frame);
1070 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1071 		}
1072 
1073 		if (!!(frame.flags & CAN_FRAME_FDF) == data->rx_cbs[alloc].fdf) {
1074 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1075 			function(dev, &frame, arg);
1076 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1077 		}
1078 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1079 
1080 		/* Setup RX message buffer to receive next message */
1081 		xfer.mbIdx = mb;
1082 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1083 		if (data->fd_mode) {
1084 			xfer.framefd = &data->rx_cbs[alloc].frame.fd;
1085 			status = FLEXCAN_TransferFDReceiveNonBlocking(config->base,
1086 								      &data->handle,
1087 								      &xfer);
1088 		} else {
1089 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1090 			xfer.frame = &data->rx_cbs[alloc].frame.classic;
1091 			status = FLEXCAN_TransferReceiveNonBlocking(config->base,
1092 								    &data->handle,
1093 								    &xfer);
1094 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1095 		}
1096 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1097 
1098 		if (status != kStatus_Success) {
1099 			LOG_ERR("Failed to restart rx for filter id %d "
1100 				"(err = %d)", alloc, status);
1101 		}
1102 	}
1103 }
1104 
FLEXCAN_CALLBACK(mcux_flexcan_transfer_callback)1105 static FLEXCAN_CALLBACK(mcux_flexcan_transfer_callback)
1106 {
1107 	struct mcux_flexcan_data *data = (struct mcux_flexcan_data *)userData;
1108 	const struct mcux_flexcan_config *config = data->dev->config;
1109 	/*
1110 	 * The result field can either be a MB index (which is limited to 32 bit
1111 	 * value) or a status flags value, which is 32 bit on some platforms but
1112 	 * 64 on others. To decouple the remaining functions from this, the
1113 	 * result field is always promoted to uint64_t.
1114 	 */
1115 	uint32_t mb = (uint32_t)result;
1116 	uint64_t status_flags = result;
1117 
1118 	ARG_UNUSED(base);
1119 
1120 	switch (status) {
1121 	case kStatus_FLEXCAN_UnHandled:
1122 		/* Not all fault confinement state changes are handled by the HAL */
1123 		__fallthrough;
1124 	case kStatus_FLEXCAN_ErrorStatus:
1125 		mcux_flexcan_transfer_error_status(data->dev, status_flags);
1126 		break;
1127 	case kStatus_FLEXCAN_TxSwitchToRx:
1128 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1129 		if (data->fd_mode) {
1130 			FLEXCAN_TransferFDAbortReceive(config->base, &data->handle, mb);
1131 		} else {
1132 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1133 			FLEXCAN_TransferAbortReceive(config->base, &data->handle, mb);
1134 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1135 		}
1136 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1137 		__fallthrough;
1138 	case kStatus_FLEXCAN_TxIdle:
1139 		mcux_flexcan_transfer_tx_idle(data->dev, mb);
1140 		break;
1141 	case kStatus_FLEXCAN_RxOverflow:
1142 		CAN_STATS_RX_OVERRUN_INC(data->dev);
1143 		__fallthrough;
1144 	case kStatus_Fail:
1145 		/* If reading an RX MB failed mark it as idle to be reprocessed. */
1146 		__fallthrough;
1147 	case kStatus_FLEXCAN_RxIdle:
1148 		mcux_flexcan_transfer_rx_idle(data->dev, mb);
1149 		break;
1150 	default:
1151 		LOG_WRN("Unhandled status 0x%08x (result = 0x%016llx)",
1152 			status, status_flags);
1153 	}
1154 }
1155 
mcux_flexcan_isr(const struct device * dev)1156 static void mcux_flexcan_isr(const struct device *dev)
1157 {
1158 	const struct mcux_flexcan_config *config = dev->config;
1159 	struct mcux_flexcan_data *data = dev->data;
1160 
1161 	FLEXCAN_TransferHandleIRQ(config->base, &data->handle);
1162 }
1163 
mcux_flexcan_init(const struct device * dev)1164 static int mcux_flexcan_init(const struct device *dev)
1165 {
1166 	const struct mcux_flexcan_config *config = dev->config;
1167 	struct mcux_flexcan_data *data = dev->data;
1168 	flexcan_config_t flexcan_config;
1169 	uint32_t clock_freq;
1170 	int err;
1171 
1172 	if (config->phy != NULL) {
1173 		if (!device_is_ready(config->phy)) {
1174 			LOG_ERR("CAN transceiver not ready");
1175 			return -ENODEV;
1176 		}
1177 	}
1178 
1179 	if (!device_is_ready(config->clock_dev)) {
1180 		LOG_ERR("clock device not ready");
1181 		return -ENODEV;
1182 	}
1183 
1184 	k_mutex_init(&data->rx_mutex);
1185 	k_mutex_init(&data->tx_mutex);
1186 	k_sem_init(&data->tx_allocs_sem, MCUX_FLEXCAN_MAX_TX,
1187 		   MCUX_FLEXCAN_MAX_TX);
1188 
1189 	data->timing.sjw = config->sjw;
1190 	if (config->sample_point && USE_SP_ALGO) {
1191 		err = can_calc_timing(dev, &data->timing, config->bitrate,
1192 				      config->sample_point);
1193 		if (err == -EINVAL) {
1194 			LOG_ERR("Can't find timing for given param");
1195 			return -EIO;
1196 		}
1197 		LOG_DBG("Presc: %d, Seg1S1: %d, Seg2: %d",
1198 			data->timing.prescaler, data->timing.phase_seg1,
1199 			data->timing.phase_seg2);
1200 		LOG_DBG("Sample-point err : %d", err);
1201 	} else {
1202 		data->timing.sjw = config->sjw;
1203 		data->timing.prop_seg = config->prop_seg;
1204 		data->timing.phase_seg1 = config->phase_seg1;
1205 		data->timing.phase_seg2 = config->phase_seg2;
1206 		err = can_calc_prescaler(dev, &data->timing, config->bitrate);
1207 		if (err) {
1208 			LOG_WRN("Bitrate error: %d", err);
1209 		}
1210 	}
1211 
1212 	/* Validate initial timing parameters */
1213 	err = can_set_timing(dev, &data->timing);
1214 	if (err != 0) {
1215 		LOG_ERR("failed to set timing (err %d)", err);
1216 		return -ENODEV;
1217 	}
1218 
1219 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1220 	if (config->flexcan_fd) {
1221 		data->timing_data.sjw = config->sjw_data;
1222 		if (config->sample_point_data && USE_SP_ALGO) {
1223 			err = can_calc_timing_data(dev, &data->timing_data, config->bitrate_data,
1224 					config->sample_point_data);
1225 			if (err == -EINVAL) {
1226 				LOG_ERR("Can't find timing for given param");
1227 				return -EIO;
1228 			}
1229 			LOG_DBG("Presc: %d, Seg1S1: %d, Seg2: %d",
1230 				data->timing_data.prescaler, data->timing_data.phase_seg1,
1231 				data->timing_data.phase_seg2);
1232 			LOG_DBG("Sample-point err : %d", err);
1233 		} else {
1234 			data->timing_data.sjw = config->sjw_data;
1235 			data->timing_data.prop_seg = config->prop_seg_data;
1236 			data->timing_data.phase_seg1 = config->phase_seg1_data;
1237 			data->timing_data.phase_seg2 = config->phase_seg2_data;
1238 			err = can_calc_prescaler(dev, &data->timing_data, config->bitrate_data);
1239 			if (err) {
1240 				LOG_WRN("Bitrate error: %d", err);
1241 			}
1242 		}
1243 	}
1244 
1245 	/* Validate initial data phase timing parameters */
1246 	err = can_set_timing_data(dev, &data->timing_data);
1247 	if (err != 0) {
1248 		LOG_ERR("failed to set data phase timing (err %d)", err);
1249 		return -ENODEV;
1250 	}
1251 
1252 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1253 
1254 	err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
1255 	if (err != 0) {
1256 		return err;
1257 	}
1258 
1259 	err = mcux_flexcan_get_core_clock(dev, &clock_freq);
1260 	if (err != 0) {
1261 		return -EIO;
1262 	}
1263 
1264 	data->dev = dev;
1265 
1266 	FLEXCAN_GetDefaultConfig(&flexcan_config);
1267 	flexcan_config.maxMbNum = MCUX_FLEXCAN_MAX_MB;
1268 	flexcan_config.clkSrc = config->clk_source;
1269 	flexcan_config.baudRate = clock_freq /
1270 	      (1U + data->timing.prop_seg + data->timing.phase_seg1 +
1271 	       data->timing.phase_seg2) / data->timing.prescaler;
1272 
1273 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1274 	if (config->flexcan_fd) {
1275 		flexcan_config.baudRateFD = clock_freq /
1276 			(1U + data->timing_data.prop_seg + data->timing_data.phase_seg1 +
1277 			 data->timing_data.phase_seg2) / data->timing_data.prescaler;
1278 	}
1279 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1280 
1281 	flexcan_config.enableIndividMask = true;
1282 	flexcan_config.enableLoopBack = false;
1283 	flexcan_config.disableSelfReception = true;
1284 	/* Initialize in listen-only mode since FLEXCAN_{FD}Init() exits freeze mode */
1285 	flexcan_config.enableListenOnlyMode = true;
1286 
1287 	flexcan_config.timingConfig.rJumpwidth = data->timing.sjw - 1U;
1288 	flexcan_config.timingConfig.propSeg = data->timing.prop_seg - 1U;
1289 	flexcan_config.timingConfig.phaseSeg1 = data->timing.phase_seg1 - 1U;
1290 	flexcan_config.timingConfig.phaseSeg2 = data->timing.phase_seg2 - 1U;
1291 
1292 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1293 	if (config->flexcan_fd) {
1294 		flexcan_config.timingConfig.frJumpwidth = data->timing_data.sjw - 1U;
1295 		flexcan_config.timingConfig.fpropSeg = data->timing_data.prop_seg;
1296 		flexcan_config.timingConfig.fphaseSeg1 = data->timing_data.phase_seg1 - 1U;
1297 		flexcan_config.timingConfig.fphaseSeg2 = data->timing_data.phase_seg2 - 1U;
1298 
1299 		FLEXCAN_FDInit(config->base, &flexcan_config, clock_freq, kFLEXCAN_64BperMB, true);
1300 	} else {
1301 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1302 		FLEXCAN_Init(config->base, &flexcan_config, clock_freq);
1303 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1304 	}
1305 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1306 
1307 	FLEXCAN_TransferCreateHandle(config->base, &data->handle,
1308 				     mcux_flexcan_transfer_callback, data);
1309 
1310 	/* Manually enter freeze mode, set normal mode, and clear error counters */
1311 	FLEXCAN_EnterFreezeMode(config->base);
1312 	(void)mcux_flexcan_set_mode(dev, CAN_MODE_NORMAL);
1313 	config->base->ECR &= ~(CAN_ECR_TXERRCNT_MASK | CAN_ECR_RXERRCNT_MASK);
1314 
1315 	config->irq_config_func(dev);
1316 
1317 #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
1318 	config->base->CTRL1 |= CAN_CTRL1_BOFFREC_MASK;
1319 #endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
1320 
1321 	(void)mcux_flexcan_get_state(dev, &data->state, NULL);
1322 
1323 	return 0;
1324 }
1325 
1326 __maybe_unused static const struct can_driver_api mcux_flexcan_driver_api = {
1327 	.get_capabilities = mcux_flexcan_get_capabilities,
1328 	.start = mcux_flexcan_start,
1329 	.stop = mcux_flexcan_stop,
1330 	.set_mode = mcux_flexcan_set_mode,
1331 	.set_timing = mcux_flexcan_set_timing,
1332 	.send = mcux_flexcan_send,
1333 	.add_rx_filter = mcux_flexcan_add_rx_filter,
1334 	.remove_rx_filter = mcux_flexcan_remove_rx_filter,
1335 	.get_state = mcux_flexcan_get_state,
1336 #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
1337 	.recover = mcux_flexcan_recover,
1338 #endif
1339 	.set_state_change_callback = mcux_flexcan_set_state_change_callback,
1340 	.get_core_clock = mcux_flexcan_get_core_clock,
1341 	.get_max_filters = mcux_flexcan_get_max_filters,
1342 	.get_max_bitrate = mcux_flexcan_get_max_bitrate,
1343 	/*
1344 	 * FlexCAN timing limits are specified in the "FLEXCANx_CTRL1 field
1345 	 * descriptions" table in the SoC reference manual.
1346 	 *
1347 	 * Note that the values here are the "physical" timing limits, whereas
1348 	 * the register field limits are physical values minus 1 (which is
1349 	 * handled by the flexcan_timing_config_t field assignments elsewhere
1350 	 * in this driver).
1351 	 */
1352 	.timing_min = {
1353 		.sjw = 0x01,
1354 		.prop_seg = 0x01,
1355 		.phase_seg1 = 0x01,
1356 		.phase_seg2 = 0x02,
1357 		.prescaler = 0x01
1358 	},
1359 	.timing_max = {
1360 		.sjw = 0x04,
1361 		.prop_seg = 0x08,
1362 		.phase_seg1 = 0x08,
1363 		.phase_seg2 = 0x08,
1364 		.prescaler = 0x100
1365 	}
1366 };
1367 
1368 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1369 static const struct can_driver_api mcux_flexcan_fd_driver_api = {
1370 	.get_capabilities = mcux_flexcan_get_capabilities,
1371 	.start = mcux_flexcan_start,
1372 	.stop = mcux_flexcan_stop,
1373 	.set_mode = mcux_flexcan_set_mode,
1374 	.set_timing = mcux_flexcan_set_timing,
1375 	.set_timing_data = mcux_flexcan_set_timing_data,
1376 	.send = mcux_flexcan_send,
1377 	.add_rx_filter = mcux_flexcan_add_rx_filter,
1378 	.remove_rx_filter = mcux_flexcan_remove_rx_filter,
1379 	.get_state = mcux_flexcan_get_state,
1380 #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
1381 	.recover = mcux_flexcan_recover,
1382 #endif
1383 	.set_state_change_callback = mcux_flexcan_set_state_change_callback,
1384 	.get_core_clock = mcux_flexcan_get_core_clock,
1385 	.get_max_filters = mcux_flexcan_get_max_filters,
1386 	.get_max_bitrate = mcux_flexcan_get_max_bitrate,
1387 	/*
1388 	 * FlexCAN FD timing limits are specified in the "CAN Bit Timing
1389 	 * Register (CBT)" and "CAN FD Bit Timing Register" field description
1390 	 * tables in the SoC reference manual.
1391 	 *
1392 	 * Note that the values here are the "physical" timing limits, whereas
1393 	 * the register field limits are physical values minus 1 (which is
1394 	 * handled by the flexcan_timing_config_t field assignments elsewhere
1395 	 * in this driver). The exception to this are the prop_seg values for
1396 	 * the data phase, which correspond to the allowed register values.
1397 	 */
1398 	.timing_min = {
1399 		.sjw = 0x01,
1400 		.prop_seg = 0x01,
1401 		.phase_seg1 = 0x01,
1402 		.phase_seg2 = 0x02,
1403 		.prescaler = 0x01
1404 	},
1405 	.timing_max = {
1406 		.sjw = 0x20,
1407 		.prop_seg = 0x40,
1408 		.phase_seg1 = 0x20,
1409 		.phase_seg2 = 0x20,
1410 		.prescaler = 0x400
1411 	},
1412 	.timing_data_min = {
1413 		.sjw = 0x01,
1414 		.prop_seg = 0x01,
1415 		.phase_seg1 = 0x01,
1416 		.phase_seg2 = 0x02,
1417 		.prescaler = 0x01
1418 	},
1419 	.timing_data_max = {
1420 		.sjw = 0x08,
1421 		.prop_seg = 0x1f,
1422 		.phase_seg1 = 0x08,
1423 		.phase_seg2 = 0x08,
1424 		.prescaler = 0x400
1425 	},
1426 };
1427 #endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1428 
1429 #define FLEXCAN_IRQ_BY_IDX(node_id, prop, idx, cell) \
1430 	DT_IRQ_BY_NAME(node_id, \
1431 		DT_STRING_TOKEN_BY_IDX(node_id, prop, idx), cell)
1432 
1433 #define FLEXCAN_IRQ_ENABLE_CODE(node_id, prop, idx) \
1434 	irq_enable(FLEXCAN_IRQ_BY_IDX(node_id, prop, idx, irq));
1435 
1436 #define FLEXCAN_IRQ_DISABLE_CODE(node_id, prop, idx) \
1437 	irq_disable(FLEXCAN_IRQ_BY_IDX(node_id, prop, idx, irq));
1438 
1439 #define FLEXCAN_IRQ_CONFIG_CODE(node_id, prop, idx) \
1440 	do {								\
1441 		IRQ_CONNECT(FLEXCAN_IRQ_BY_IDX(node_id, prop, idx, irq), \
1442 		FLEXCAN_IRQ_BY_IDX(node_id, prop, idx, priority), \
1443 		mcux_flexcan_isr, \
1444 		DEVICE_DT_GET(node_id), 0); \
1445 		FLEXCAN_IRQ_ENABLE_CODE(node_id, prop, idx); \
1446 	} while (false);
1447 
1448 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1449 #define FLEXCAN_MAX_BITRATE(id)							\
1450 	COND_CODE_1(DT_NODE_HAS_COMPAT(DT_DRV_INST(id), FLEXCAN_FD_DRV_COMPAT),	\
1451 		    (8000000), (1000000))
1452 #else /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1453 #define FLEXCAN_MAX_BITRATE(id) 1000000
1454 #endif /* !CONFIG_CAN_MCUX_FLEXCAN_FD */
1455 
1456 #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
1457 #define FLEXCAN_DRIVER_API(id)							\
1458 	COND_CODE_1(DT_NODE_HAS_COMPAT(DT_DRV_INST(id), FLEXCAN_FD_DRV_COMPAT),	\
1459 		    (mcux_flexcan_fd_driver_api),				\
1460 		    (mcux_flexcan_driver_api))
1461 #else /* CONFIG_CAN_MCUX_FLEXCAN_FD */
1462 #define FLEXCAN_DRIVER_API(id) mcux_flexcan_driver_api
1463 #endif /* !CONFIG_CAN_MCUX_FLEXCAN_FD */
1464 
1465 #define FLEXCAN_DEVICE_INIT_MCUX(id)					\
1466 	PINCTRL_DT_INST_DEFINE(id);					\
1467 									\
1468 	static void mcux_flexcan_irq_config_##id(const struct device *dev); \
1469 	static void mcux_flexcan_irq_enable_##id(void); \
1470 	static void mcux_flexcan_irq_disable_##id(void); \
1471 									\
1472 	static const struct mcux_flexcan_config mcux_flexcan_config_##id = { \
1473 		.base = (CAN_Type *)DT_INST_REG_ADDR(id),		\
1474 		.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)),	\
1475 		.clock_subsys = (clock_control_subsys_t)		\
1476 			DT_INST_CLOCKS_CELL(id, name),			\
1477 		.clk_source = DT_INST_PROP(id, clk_source),		\
1478 		.bitrate = DT_INST_PROP(id, bus_speed),			\
1479 		.sjw = DT_INST_PROP(id, sjw),				\
1480 		.prop_seg = DT_INST_PROP_OR(id, prop_seg, 0),		\
1481 		.phase_seg1 = DT_INST_PROP_OR(id, phase_seg1, 0),	\
1482 		.phase_seg2 = DT_INST_PROP_OR(id, phase_seg2, 0),	\
1483 		.sample_point = DT_INST_PROP_OR(id, sample_point, 0),	\
1484 		IF_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD, (		\
1485 			.flexcan_fd = DT_NODE_HAS_COMPAT(DT_DRV_INST(id), FLEXCAN_FD_DRV_COMPAT), \
1486 			.bitrate_data = DT_INST_PROP_OR(id, bus_speed_data, 0),		\
1487 			.sjw_data = DT_INST_PROP_OR(id, sjw_data, 0),			\
1488 			.prop_seg_data = DT_INST_PROP_OR(id, prop_seg_data, 0),		\
1489 			.phase_seg1_data = DT_INST_PROP_OR(id, phase_seg1_data, 0),	\
1490 			.phase_seg2_data = DT_INST_PROP_OR(id, phase_seg2_data, 0),	\
1491 			.sample_point_data = DT_INST_PROP_OR(id, sample_point_data, 0),	\
1492 		))							\
1493 		.irq_config_func = mcux_flexcan_irq_config_##id,	\
1494 		.irq_enable_func = mcux_flexcan_irq_enable_##id,	\
1495 		.irq_disable_func = mcux_flexcan_irq_disable_##id,	\
1496 		.phy = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(id, phys)),\
1497 		.max_bitrate = DT_INST_CAN_TRANSCEIVER_MAX_BITRATE(id,	\
1498 			FLEXCAN_MAX_BITRATE(id)),			\
1499 		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id),		\
1500 	};								\
1501 									\
1502 	static struct mcux_flexcan_data mcux_flexcan_data_##id;		\
1503 									\
1504 	CAN_DEVICE_DT_INST_DEFINE(id, mcux_flexcan_init,		\
1505 				  NULL, &mcux_flexcan_data_##id,	\
1506 				  &mcux_flexcan_config_##id,		\
1507 				  POST_KERNEL, CONFIG_CAN_INIT_PRIORITY,\
1508 				  &FLEXCAN_DRIVER_API(id));		\
1509 									\
1510 	static void mcux_flexcan_irq_config_##id(const struct device *dev) \
1511 	{								\
1512 		DT_INST_FOREACH_PROP_ELEM(id, interrupt_names, FLEXCAN_IRQ_CONFIG_CODE); \
1513 	} \
1514 									\
1515 	static void mcux_flexcan_irq_enable_##id(void) \
1516 	{								\
1517 		DT_INST_FOREACH_PROP_ELEM(id, interrupt_names, FLEXCAN_IRQ_ENABLE_CODE); \
1518 	} \
1519 									\
1520 	static void mcux_flexcan_irq_disable_##id(void) \
1521 	{								\
1522 		DT_INST_FOREACH_PROP_ELEM(id, interrupt_names, FLEXCAN_IRQ_DISABLE_CODE); \
1523 	}
1524 
1525 DT_INST_FOREACH_STATUS_OKAY(FLEXCAN_DEVICE_INIT_MCUX)
1526