@@ -33,20 +33,6 @@ LOG_MODULE_REGISTER(can_mcux_flexcan, CONFIG_CAN_LOG_LEVEL);
3333#define RX_START_IDX 0
3434#endif
3535
36- /* The maximum number of message buffers for concurrent active instances */
37- #ifdef CONFIG_CAN_MAX_MB
38- #define MCUX_FLEXCAN_MAX_MB CONFIG_CAN_MAX_MB
39- #else
40- #define MCUX_FLEXCAN_MAX_MB FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0)
41- #endif
42-
43- /*
44- * RX message buffers (filters) will take up the first N message
45- * buffers. The rest are available for TX use.
46- */
47- #define MCUX_FLEXCAN_MAX_RX (CONFIG_CAN_MAX_FILTER + RX_START_IDX)
48- #define MCUX_FLEXCAN_MAX_TX (MCUX_FLEXCAN_MAX_MB - MCUX_FLEXCAN_MAX_RX)
49-
5036/*
5137 * Convert from RX message buffer index to allocated filter ID and
5238 * vice versa.
@@ -58,8 +44,8 @@ LOG_MODULE_REGISTER(can_mcux_flexcan, CONFIG_CAN_LOG_LEVEL);
5844 * Convert from TX message buffer index to allocated TX ID and vice
5945 * versa.
6046 */
61- #define TX_MBIDX_TO_ALLOC_IDX (x ) (x - MCUX_FLEXCAN_MAX_RX )
62- #define ALLOC_IDX_TO_TXMB_IDX (x ) (x + MCUX_FLEXCAN_MAX_RX )
47+ #define TX_MBIDX_TO_ALLOC_IDX (x ) (x - ((const struct mcux_flexcan_config *)dev->config)->rx_mb )
48+ #define ALLOC_IDX_TO_TXMB_IDX (x ) (x + ((const struct mcux_flexcan_config *)dev->config)->rx_mb )
6349
6450/* Convert from back from FLEXCAN IDs to Zephyr CAN IDs. */
6551#define FLEXCAN_ID_TO_CAN_ID_STD (id ) \
@@ -79,6 +65,9 @@ struct mcux_flexcan_config {
7965 const struct device * clock_dev ;
8066 clock_control_subsys_t clock_subsys ;
8167 int clk_source ;
68+ uint32_t max_mb ;
69+ uint32_t rx_mb ;
70+ uint32_t tx_mb ;
8271#ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
8372 bool flexcan_fd ;
8473#endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
@@ -113,16 +102,18 @@ struct mcux_flexcan_data {
113102 const struct device * dev ;
114103 flexcan_handle_t handle ;
115104
116- ATOMIC_DEFINE (rx_allocs , MCUX_FLEXCAN_MAX_RX );
117- struct k_mutex rx_mutex ;
118- struct mcux_flexcan_rx_callback rx_cbs [MCUX_FLEXCAN_MAX_RX ];
119-
120- ATOMIC_DEFINE (tx_allocs , MCUX_FLEXCAN_MAX_TX );
121- struct k_sem tx_allocs_sem ;
122- struct k_mutex tx_mutex ;
123- struct mcux_flexcan_tx_callback tx_cbs [MCUX_FLEXCAN_MAX_TX ];
124105 enum can_state state ;
125106 struct can_timing timing ;
107+
108+ atomic_t * rx_allocs ;
109+ atomic_t * tx_allocs ;
110+ struct mcux_flexcan_rx_callback * rx_cbs ;
111+ struct mcux_flexcan_tx_callback * tx_cbs ;
112+
113+ struct k_mutex rx_mutex ;
114+ struct k_mutex tx_mutex ;
115+ struct k_sem tx_allocs_sem ;
116+
126117#ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
127118 struct can_timing timing_data ;
128119#endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
@@ -204,12 +195,13 @@ static int mcux_flexcan_get_capabilities(const struct device *dev, can_mode_t *c
204195
205196static status_t mcux_flexcan_mb_start (const struct device * dev , int alloc )
206197{
198+ __maybe_unused const struct mcux_flexcan_config * config = dev -> config ;
207199 struct mcux_flexcan_data * data = dev -> data ;
208200 CAN_Type * base = get_base (dev );
209201 flexcan_mb_transfer_t xfer ;
210202 status_t status ;
211203
212- __ASSERT_NO_MSG (alloc >= 0 && alloc < ARRAY_SIZE ( data -> rx_cbs ) );
204+ __ASSERT_NO_MSG (alloc >= 0 && alloc < config -> rx_mb );
213205
214206 xfer .mbIdx = ALLOC_IDX_TO_RXMB_IDX (alloc );
215207
@@ -234,10 +226,11 @@ static status_t mcux_flexcan_mb_start(const struct device *dev, int alloc)
234226
235227static void mcux_flexcan_mb_stop (const struct device * dev , int alloc )
236228{
229+ __maybe_unused const struct mcux_flexcan_config * config = dev -> config ;
237230 struct mcux_flexcan_data * data = dev -> data ;
238231 CAN_Type * base = get_base (dev );
239232
240- __ASSERT_NO_MSG (alloc >= 0 && alloc < ARRAY_SIZE ( data -> rx_cbs ) );
233+ __ASSERT_NO_MSG (alloc >= 0 && alloc < config -> rx_mb );
241234
242235#ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
243236 if ((data -> common .mode & CAN_MODE_FD ) != 0U ) {
@@ -288,7 +281,7 @@ static int mcux_flexcan_start(const struct device *dev)
288281 /* Re-add all RX filters using current mode */
289282 k_mutex_lock (& data -> rx_mutex , K_FOREVER );
290283
291- for (alloc = RX_START_IDX ; alloc < MCUX_FLEXCAN_MAX_RX ; alloc ++ ) {
284+ for (alloc = RX_START_IDX ; alloc < config -> rx_mb ; alloc ++ ) {
292285 if (atomic_test_bit (data -> rx_allocs , alloc )) {
293286 status = mcux_flexcan_mb_start (dev , alloc );
294287 if (status != kStatus_Success ) {
@@ -351,7 +344,7 @@ static int mcux_flexcan_stop(const struct device *dev)
351344 data -> common .started = false;
352345
353346 /* Abort any pending TX frames before entering freeze mode */
354- for (alloc = 0 ; alloc < MCUX_FLEXCAN_MAX_TX ; alloc ++ ) {
347+ for (alloc = 0 ; alloc < config -> tx_mb ; alloc ++ ) {
355348 function = data -> tx_cbs [alloc ].function ;
356349 arg = data -> tx_cbs [alloc ].arg ;
357350
@@ -382,7 +375,7 @@ static int mcux_flexcan_stop(const struct device *dev)
382375 */
383376 k_mutex_lock (& data -> rx_mutex , K_FOREVER );
384377
385- for (alloc = RX_START_IDX ; alloc < MCUX_FLEXCAN_MAX_RX ; alloc ++ ) {
378+ for (alloc = RX_START_IDX ; alloc < config -> rx_mb ; alloc ++ ) {
386379 if (atomic_test_bit (data -> rx_allocs , alloc )) {
387380 mcux_flexcan_mb_stop (dev , alloc );
388381 }
@@ -744,7 +737,7 @@ static int mcux_flexcan_send(const struct device *dev,
744737 return - EAGAIN ;
745738 }
746739
747- for (alloc = 0 ; alloc < MCUX_FLEXCAN_MAX_TX ; alloc ++ ) {
740+ for (alloc = 0 ; alloc < config -> tx_mb ; alloc ++ ) {
748741 if (!atomic_test_and_set_bit (data -> tx_allocs , alloc )) {
749742 break ;
750743 }
@@ -799,9 +792,7 @@ static int mcux_flexcan_add_rx_filter(const struct device *dev,
799792 void * user_data ,
800793 const struct can_filter * filter )
801794{
802- #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
803795 const struct mcux_flexcan_config * config = dev -> config ;
804- #endif
805796 struct mcux_flexcan_data * data = dev -> data ;
806797 CAN_Type * base = get_base (dev );
807798 status_t status ;
@@ -817,7 +808,7 @@ static int mcux_flexcan_add_rx_filter(const struct device *dev,
817808 k_mutex_lock (& data -> rx_mutex , K_FOREVER );
818809
819810 /* Find and allocate RX message buffer */
820- for (i = RX_START_IDX ; i < MCUX_FLEXCAN_MAX_RX ; i ++ ) {
811+ for (i = RX_START_IDX ; i < config -> rx_mb ; i ++ ) {
821812 if (!atomic_test_and_set_bit (data -> rx_allocs , i )) {
822813 alloc = i ;
823814 break ;
@@ -918,9 +909,10 @@ static int mcux_flexcan_recover(const struct device *dev, k_timeout_t timeout)
918909
919910static void mcux_flexcan_remove_rx_filter (const struct device * dev , int filter_id )
920911{
912+ const struct mcux_flexcan_config * config = dev -> config ;
921913 struct mcux_flexcan_data * data = dev -> data ;
922914
923- if (filter_id < 0 || filter_id >= MCUX_FLEXCAN_MAX_RX ) {
915+ if (filter_id < 0 || filter_id >= config -> rx_mb ) {
924916 LOG_ERR ("filter ID %d out of bounds" , filter_id );
925917 return ;
926918 }
@@ -929,8 +921,6 @@ static void mcux_flexcan_remove_rx_filter(const struct device *dev, int filter_i
929921
930922 if (atomic_test_and_clear_bit (data -> rx_allocs , filter_id )) {
931923#ifdef CONFIG_CAN_MCUX_FLEXCAN_FD
932- const struct mcux_flexcan_config * config = dev -> config ;
933-
934924 /* Stop FlexCAN FD MBs unless already in stopped mode */
935925 if (!config -> flexcan_fd || data -> common .started ) {
936926#endif /* CONFIG_CAN_MCUX_FLEXCAN_FD */
@@ -951,6 +941,7 @@ static void mcux_flexcan_remove_rx_filter(const struct device *dev, int filter_i
951941static inline void mcux_flexcan_transfer_error_status (const struct device * dev ,
952942 uint64_t error )
953943{
944+ const struct mcux_flexcan_config * config = dev -> config ;
954945 struct mcux_flexcan_data * data = dev -> data ;
955946 CAN_Type * base = get_base (dev );
956947 const can_state_change_callback_t cb = data -> common .state_change_cb ;
@@ -996,7 +987,7 @@ static inline void mcux_flexcan_transfer_error_status(const struct device *dev,
996987
997988 if (state == CAN_STATE_BUS_OFF ) {
998989 /* Abort any pending TX frames in case of bus-off */
999- for (alloc = 0 ; alloc < MCUX_FLEXCAN_MAX_TX ; alloc ++ ) {
990+ for (alloc = 0 ; alloc < config -> tx_mb ; alloc ++ ) {
1000991 /* Copy callback function and argument before clearing bit */
1001992 function = data -> tx_cbs [alloc ].function ;
1002993 arg = data -> tx_cbs [alloc ].arg ;
@@ -1176,10 +1167,12 @@ static int mcux_flexcan_init(const struct device *dev)
11761167
11771168 DEVICE_MMIO_NAMED_MAP (dev , flexcan_mmio , K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP );
11781169
1170+ LOG_DBG ("Message Buffers: %d, RX MB: %d, TX MB: %d" ,
1171+ config -> max_mb , config -> rx_mb , config -> tx_mb );
1172+
11791173 k_mutex_init (& data -> rx_mutex );
11801174 k_mutex_init (& data -> tx_mutex );
1181- k_sem_init (& data -> tx_allocs_sem , MCUX_FLEXCAN_MAX_TX ,
1182- MCUX_FLEXCAN_MAX_TX );
1175+ k_sem_init (& data -> tx_allocs_sem , config -> tx_mb , config -> tx_mb );
11831176
11841177 err = can_calc_timing (dev , & data -> timing , config -> common .bitrate ,
11851178 config -> common .sample_point );
@@ -1235,7 +1228,7 @@ static int mcux_flexcan_init(const struct device *dev)
12351228 data -> dev = dev ;
12361229
12371230 FLEXCAN_GetDefaultConfig (& flexcan_config );
1238- flexcan_config .maxMbNum = MCUX_FLEXCAN_MAX_MB ;
1231+ flexcan_config .maxMbNum = config -> max_mb ;
12391232 flexcan_config .clkSrc = config -> clk_source ;
12401233 flexcan_config .baudRate = clock_freq /
12411234 (1U + data -> timing .prop_seg + data -> timing .phase_seg1 +
@@ -1432,20 +1425,54 @@ static DEVICE_API(can, mcux_flexcan_fd_driver_api) = {
14321425#define FLEXCAN_DRIVER_API (id ) mcux_flexcan_driver_api
14331426#endif /* !CONFIG_CAN_MCUX_FLEXCAN_FD */
14341427
1428+ #define FLEXCAN_INST_MAX_MB (id ) \
1429+ COND_CODE_1(UTIL_AND(IS_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD), \
1430+ DT_INST_NODE_HAS_COMPAT(id, FLEXCAN_FD_DRV_COMPAT)), \
1431+ (DT_INST_PROP(id, nxp_max_mb_fd)), \
1432+ (DT_INST_PROP(id, nxp_max_mb)))
1433+
1434+ /*
1435+ * RX message buffers (filters) will take up the first N message
1436+ * buffers. The rest are available for TX use.
1437+ */
1438+ #define FLEXCAN_INST_RX_MB (id ) (CONFIG_CAN_MAX_FILTER + RX_START_IDX)
1439+ #define FLEXCAN_INST_TX_MB (id ) (FLEXCAN_INST_MAX_MB(id) - FLEXCAN_INST_RX_MB(id))
1440+
1441+ #define FLEXCAN_CHECK_MAX_FILTER (id ) \
1442+ BUILD_ASSERT(FLEXCAN_INST_MAX_MB(id) >= FLEXCAN_INST_RX_MB(id), \
1443+ "FlexCAN instance " STRINGIFY(id) " max-mb (" \
1444+ STRINGIFY(FLEXCAN_INST_MAX_MB(id)) \
1445+ ") is too small for required RX filters (" \
1446+ STRINGIFY(FLEXCAN_INST_RX_MB(id)) ")")
1447+
14351448#define FLEXCAN_DEVICE_INIT_MCUX (id ) \
14361449 PINCTRL_DT_INST_DEFINE(id); \
1450+ FLEXCAN_CHECK_MAX_FILTER(id); \
14371451 \
14381452 static void mcux_flexcan_irq_config_##id(const struct device *dev); \
14391453 static void mcux_flexcan_irq_enable_##id(void); \
14401454 static void mcux_flexcan_irq_disable_##id(void); \
14411455 \
1456+ static struct mcux_flexcan_rx_callback flexcan_rx_cbs_##id \
1457+ [FLEXCAN_INST_RX_MB(id)] = {0}; \
1458+ \
1459+ static struct mcux_flexcan_tx_callback flexcan_tx_cbs_##id \
1460+ [FLEXCAN_INST_TX_MB(id)] = {0}; \
1461+ \
1462+ static ATOMIC_DEFINE(flexcan_rx_allocs_##id, FLEXCAN_INST_RX_MB(id)); \
1463+ \
1464+ static ATOMIC_DEFINE(flexcan_tx_allocs_##id, FLEXCAN_INST_TX_MB(id)); \
1465+ \
14421466 static const struct mcux_flexcan_config mcux_flexcan_config_##id = { \
14431467 DEVICE_MMIO_NAMED_ROM_INIT(flexcan_mmio, DT_DRV_INST(id)), \
14441468 .common = CAN_DT_DRIVER_CONFIG_INST_GET(id, 0, FLEXCAN_MAX_BITRATE(id)), \
14451469 .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \
14461470 .clock_subsys = (clock_control_subsys_t) \
14471471 DT_INST_CLOCKS_CELL(id, name), \
14481472 .clk_source = DT_INST_PROP(id, clk_source), \
1473+ .max_mb = FLEXCAN_INST_MAX_MB(id), \
1474+ .rx_mb = FLEXCAN_INST_RX_MB(id), \
1475+ .tx_mb = FLEXCAN_INST_TX_MB(id), \
14491476 IF_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD, ( \
14501477 .flexcan_fd = DT_INST_NODE_HAS_COMPAT(id, FLEXCAN_FD_DRV_COMPAT), \
14511478 )) \
@@ -1455,7 +1482,12 @@ static DEVICE_API(can, mcux_flexcan_fd_driver_api) = {
14551482 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \
14561483 }; \
14571484 \
1458- static struct mcux_flexcan_data mcux_flexcan_data_##id; \
1485+ static struct mcux_flexcan_data mcux_flexcan_data_##id = { \
1486+ .rx_cbs = flexcan_rx_cbs_##id, \
1487+ .tx_cbs = flexcan_tx_cbs_##id, \
1488+ .rx_allocs = flexcan_rx_allocs_##id, \
1489+ .tx_allocs = flexcan_tx_allocs_##id, \
1490+ }; \
14591491 \
14601492 CAN_DEVICE_DT_INST_DEFINE(id, mcux_flexcan_init, \
14611493 NULL, &mcux_flexcan_data_##id, \
0 commit comments