1 /*
2 * Copyright (c) 2024, Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9 #include <zephyr/drivers/mbox.h>
10
11 int dummy_value;
12
13 #if defined(CONFIG_SOC_NRF54L05) || defined(CONFIG_SOC_NRF54L10) || \
14 defined(CONFIG_SOC_NRF54L15) || defined(CONFIG_SOC_NRF54H20)
15 #define EXPECTED_MTU_VALUE (0)
16 #define DATA_TRANSFER_MODE_SUPPORTED (0)
17 #define REMOTE_BUSY_SUPPORTED (0)
18 #else
19 #define EXPECTED_MTU_VALUE (4)
20 #define DATA_TRANSFER_MODE_SUPPORTED (1)
21 #define REMOTE_BUSY_SUPPORTED (1)
22 #endif
23
dummy_callback(const struct device * dev,mbox_channel_id_t channel_id,void * user_data,struct mbox_msg * data)24 static void dummy_callback(const struct device *dev, mbox_channel_id_t channel_id,
25 void *user_data, struct mbox_msg *data)
26 {
27 ARG_UNUSED(dev);
28 ARG_UNUSED(channel_id);
29 ARG_UNUSED(user_data);
30 ARG_UNUSED(data);
31 /* Nothing here */
32 }
33
dummy_callback_2(const struct device * dev,mbox_channel_id_t channel_id,void * user_data,struct mbox_msg * data)34 static void dummy_callback_2(const struct device *dev, mbox_channel_id_t channel_id,
35 void *user_data, struct mbox_msg *data)
36 {
37 ARG_UNUSED(dev);
38 ARG_UNUSED(channel_id);
39 ARG_UNUSED(data);
40
41 int *temp = (int *) user_data;
42 (*temp)++;
43 }
44
45 /**
46 * @brief mbox_is_ready_dt() positive test
47 *
48 * Confirm that mbox_is_ready_dt() returns True
49 * on valid local and remote mbox channels.
50 *
51 */
ZTEST(mbox_error_cases,test_01a_mbox_is_ready_positive)52 ZTEST(mbox_error_cases, test_01a_mbox_is_ready_positive)
53 {
54 const struct mbox_dt_spec rx_channel =
55 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_valid);
56 const struct mbox_dt_spec tx_channel =
57 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_valid);
58 bool ret;
59
60 ret = mbox_is_ready_dt(&tx_channel);
61 zassert_true(
62 ret,
63 "mbox_is_ready_dt(tx_channel) should return True,"
64 " got unexpected value of %d",
65 ret
66 );
67
68 ret = mbox_is_ready_dt(&rx_channel);
69 zassert_true(
70 ret,
71 "mbox_is_ready_dt(rx_channel) should return True,"
72 " got unexpected value of %d",
73 ret
74 );
75 }
76
77 /**
78 * @brief mbox_is_ready_dt() on incorrect channels
79 *
80 * Confirm that mbox_is_ready_dt() returns True
81 * on invalid local and remote mbox channel.
82 * (Device is ready, channel is not checked.)
83 *
84 */
ZTEST(mbox_error_cases,test_01b_mbox_is_ready_negative)85 ZTEST(mbox_error_cases, test_01b_mbox_is_ready_negative)
86 {
87 const struct mbox_dt_spec rx_channel =
88 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_incorrect);
89 const struct mbox_dt_spec tx_channel =
90 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_incorrect);
91 bool ret;
92
93 ret = mbox_is_ready_dt(&tx_channel);
94 zassert_true(
95 ret,
96 "mbox_is_ready_dt(tx_invalid_channel) should return True,"
97 " got unexpected value of %d",
98 ret
99 );
100
101 ret = mbox_is_ready_dt(&rx_channel);
102 zassert_true(
103 ret,
104 "mbox_is_ready_dt(rx_invalid_channel) should return True,"
105 " got unexpected value of %d", ret
106 );
107 }
108
109 /**
110 * @brief mbox_send_dt() on invalid TX channel shall fail
111 *
112 * Confirm that mbox_send_dt() returns
113 * -EINVAL when TX channel is invalid.
114 *
115 */
ZTEST(mbox_error_cases,test_02a_mbox_send_on_invalid_tx_channel)116 ZTEST(mbox_error_cases, test_02a_mbox_send_on_invalid_tx_channel)
117 {
118 const struct mbox_dt_spec tx_channel =
119 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_incorrect);
120 int ret;
121
122 ret = mbox_send_dt(&tx_channel, NULL);
123 zassert_true(
124 (ret == -EINVAL),
125 "mbox_send_dt(incorrect_tx_channel) shall return -EINVAL (-22)"
126 " got unexpected %d",
127 ret
128 );
129 }
130
131 /**
132 * @brief mbox_send_dt() on RX channel shall fail
133 *
134 * Confirm that mbox_send_dt() returns
135 * -ENOSYS when user tries to send on RX channel.
136 *
137 */
ZTEST(mbox_error_cases,test_02b_mbox_send_on_rx_channel)138 ZTEST(mbox_error_cases, test_02b_mbox_send_on_rx_channel)
139 {
140 const struct mbox_dt_spec rx_channel =
141 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_valid);
142 int ret;
143
144 ret = mbox_send_dt(&rx_channel, NULL);
145 zassert_true(
146 (ret == -ENOSYS),
147 "mbox_send_dt(rx_channel) shall return -ENOSYS (-88)"
148 " got unexpected %d",
149 ret
150 );
151 }
152
153 /**
154 * @brief mbox_send_dt() with nonzero data field
155 *
156 * Confirm that mbox_send_dt() returns
157 * -EMSGSIZE when driver does NOT support DATA transfer.
158 *
159 */
ZTEST(mbox_error_cases,test_02c_mbox_send_message_with_data)160 ZTEST(mbox_error_cases, test_02c_mbox_send_message_with_data)
161 {
162 const struct mbox_dt_spec tx_channel =
163 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_valid);
164 struct mbox_msg data_msg = {0};
165 int ret;
166
167 if (DATA_TRANSFER_MODE_SUPPORTED) {
168 /* Skip this test because data transfer is supported. */
169 ztest_test_skip();
170 }
171
172 data_msg.data = &dummy_value;
173 data_msg.size = 4;
174
175 ret = mbox_send_dt(&tx_channel, &data_msg);
176 zassert_true(
177 (ret == -EMSGSIZE),
178 "mbox_send_dt(rx_channel, data) shall return -EMSGSIZE (-122)"
179 " got unexpected %d",
180 ret
181 );
182 }
183
184 /**
185 * @brief mbox_send_dt() remote busy
186 *
187 * Confirm that mbox_send_dt() returns
188 * -EBUSY when remote hasn’t yet read the last data sent.
189 *
190 */
ZTEST(mbox_error_cases,test_02d_mbox_send_message_remote_busy)191 ZTEST(mbox_error_cases, test_02d_mbox_send_message_remote_busy)
192 {
193 const struct mbox_dt_spec tx_channel =
194 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_valid);
195 int ret;
196
197 if (!REMOTE_BUSY_SUPPORTED) {
198 /* Skip this test because driver is not
199 * capable of detecting that remote is busy.
200 */
201 ztest_test_skip();
202 }
203
204 ret = mbox_send_dt(&tx_channel, NULL);
205 zassert_true(
206 (ret == 0),
207 "mbox_send_dt(rx_channel) shall return 0"
208 " got unexpected %d",
209 ret
210 );
211
212 ret = mbox_send_dt(&tx_channel, NULL);
213 zassert_true(
214 (ret == -EBUSY),
215 "mbox_send_dt(rx_channel) shall return -EBUSY (-16)"
216 " got unexpected %d",
217 ret
218 );
219 }
220
221 /**
222 * @brief mbox_register_callback_dt() on TX channel shall fail
223 *
224 * Confirm that mbox_register_callback_dt() returns
225 * -ENOSYS when user tries to register callback on TX mbox channel.
226 *
227 */
ZTEST(mbox_error_cases,test_03a_mbox_register_callback_on_remote_channel)228 ZTEST(mbox_error_cases, test_03a_mbox_register_callback_on_remote_channel)
229 {
230 const struct mbox_dt_spec tx_channel =
231 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_valid);
232 int ret;
233
234 ret = mbox_register_callback_dt(&tx_channel, dummy_callback, NULL);
235 zassert_true(
236 (ret == -ENOSYS),
237 "mbox_register_callback(remote_channel) shall return -ENOSYS (-88)"
238 " got unexpected %d",
239 ret
240 );
241 }
242
243 /**
244 * @brief mbox_register_callback_dt() on incorrect channel shall fail
245 *
246 * Confirm that mbox_register_callback_dt() returns
247 * -EINVAL when user tries to register callback on incorrect mbox channel.
248 *
249 */
ZTEST(mbox_error_cases,test_03b_mbox_register_callback_on_invalid_channel)250 ZTEST(mbox_error_cases, test_03b_mbox_register_callback_on_invalid_channel)
251 {
252 const struct mbox_dt_spec rx_channel =
253 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_incorrect);
254 int ret;
255
256 ret = mbox_register_callback_dt(&rx_channel, dummy_callback, NULL);
257 zassert_true(
258 (ret == -EINVAL),
259 "mbox_register_callback(incorrect_channel) shall return -EINVAL (-22)"
260 " got unexpected %d",
261 ret
262 );
263 }
264
265 /**
266 * @brief mbox_register_callback_dt() multiple use on same channel
267 *
268 * Confirm that mbox_register_callback_dt() returns
269 * 0 when user tries to register callback
270 * on already configured mbox channel.
271 *
272 */
ZTEST(mbox_error_cases,test_03c_mbox_register_callback_twice_on_same_channel)273 ZTEST(mbox_error_cases, test_03c_mbox_register_callback_twice_on_same_channel)
274 {
275 const struct mbox_dt_spec rx_channel =
276 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_valid);
277 int ret;
278
279 ret = mbox_register_callback_dt(&rx_channel, dummy_callback, NULL);
280 zassert_true(
281 (ret == 0),
282 "mbox_register_callback(valid_channel) shall return 0"
283 " got unexpected %d",
284 ret
285 );
286
287 ret = mbox_register_callback_dt(&rx_channel, dummy_callback_2, &dummy_value);
288 zassert_true(
289 (ret == 0),
290 "mbox_register_callback(valid_channel) shall return 0"
291 " got unexpected %d",
292 ret
293 );
294 }
295
296 /**
297 * @brief mbox_mtu_get_dt() on RX channel shall fail
298 *
299 * Confirm that mbox_mtu_get_dt() returns
300 * -ENOSYS for RX mbox channel.
301 *
302 */
ZTEST(mbox_error_cases,test_04a_mbox_mtu_get_on_rx_channel)303 ZTEST(mbox_error_cases, test_04a_mbox_mtu_get_on_rx_channel)
304 {
305 const struct mbox_dt_spec rx_channel =
306 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_valid);
307 int ret;
308
309 ret = mbox_mtu_get_dt(&rx_channel);
310 zassert_true(
311 (ret == -ENOSYS),
312 "mbox_mtu_get_dt(rx_channel) shall return -ENOSYS (-88)"
313 " got unexpected %d",
314 ret
315 );
316 }
317
318 /**
319 * @brief mbox_mtu_get_dt() on TX channel functional test
320 *
321 * Confirm that mbox_mtu_get_dt() returns
322 * expected value for TX mbox channel.
323 * (No matter if channel is valid or incorrect.)
324 *
325 */
ZTEST(mbox_error_cases,test_04b_mbox_mtu_get_on_tx_channel)326 ZTEST(mbox_error_cases, test_04b_mbox_mtu_get_on_tx_channel)
327 {
328 const struct mbox_dt_spec tx_channel =
329 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_valid);
330 const struct mbox_dt_spec tx_channel_incorrect =
331 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_incorrect);
332 int ret;
333
334 ret = mbox_mtu_get_dt(&tx_channel);
335 zassert_true(
336 (ret == EXPECTED_MTU_VALUE),
337 "mbox_mtu_get_dt(tx_channel) shall return %d"
338 " got unexpected %d",
339 EXPECTED_MTU_VALUE,
340 ret
341 );
342
343 ret = mbox_mtu_get_dt(&tx_channel_incorrect);
344 zassert_true(
345 (ret == EXPECTED_MTU_VALUE),
346 "mbox_mtu_get_dt(tx_channel_incorrect) shall return %d"
347 " got unexpected %d",
348 EXPECTED_MTU_VALUE,
349 ret
350 );
351 }
352
353 /**
354 * @brief mbox_set_enabled_dt() - Enable TX channel shall fail
355 *
356 * Confirm that mbox_set_enabled_dt() returns
357 * -ENOSYS for TX mbox channel.
358 *
359 */
ZTEST(mbox_error_cases,test_05a_mbox_set_enabled_on_tx_channel)360 ZTEST(mbox_error_cases, test_05a_mbox_set_enabled_on_tx_channel)
361 {
362 const struct mbox_dt_spec tx_channel =
363 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_valid);
364 int ret;
365
366 ret = mbox_set_enabled_dt(&tx_channel, true);
367 zassert_true(
368 (ret == -ENOSYS),
369 "mbox_set_enabled_dt(tx_channel, true) shall return -ENOSYS (-88)"
370 " got unexpected %d",
371 ret
372 );
373 }
374
375 /**
376 * @brief mbox_set_enabled_dt() - Enable incorrect channel shall fail
377 *
378 * Confirm that mbox_set_enabled_dt() returns
379 * -EINVAL for incorrect RX mbox channel.
380 *
381 */
ZTEST(mbox_error_cases,test_05b_mbox_set_enabled_on_incorrect_rx_channel)382 ZTEST(mbox_error_cases, test_05b_mbox_set_enabled_on_incorrect_rx_channel)
383 {
384 const struct mbox_dt_spec rx_channel =
385 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_incorrect);
386 int ret;
387
388 ret = mbox_set_enabled_dt(&rx_channel, true);
389 zassert_true(
390 (ret == -EINVAL),
391 "mbox_set_enabled_dt(incorrect_channel, true) shall return -EINVAL (-22)"
392 " got unexpected %d",
393 ret
394 );
395 }
396
397 /**
398 * @brief mbox_set_enabled_dt() - Enable already enabled channel shall fail
399 *
400 * Confirm that mbox_set_enabled_dt() returns
401 * -EALREADY when user tries to enable already enabled RX mbox channel.
402 *
403 */
ZTEST(mbox_error_cases,test_05c_mbox_set_enabled_on_already_enabled_rx_channel)404 ZTEST(mbox_error_cases, test_05c_mbox_set_enabled_on_already_enabled_rx_channel)
405 {
406 const struct mbox_dt_spec rx_channel =
407 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_valid);
408 int ret;
409
410 /* The user must take care of installing a proper callback
411 * on the channel before enabling it.
412 */
413 ret = mbox_register_callback_dt(&rx_channel, dummy_callback, NULL);
414 zassert_true(
415 (ret == 0),
416 "mbox_register_callback(tx_channel) shall return 0"
417 " got unexpected %d",
418 ret
419 );
420
421 ret = mbox_set_enabled_dt(&rx_channel, true);
422 zassert_true(
423 (ret == 0),
424 "mbox_set_enabled_dt(tx_channel, true) shall return 0"
425 " got unexpected %d",
426 ret
427 );
428
429 ret = mbox_set_enabled_dt(&rx_channel, true);
430 zassert_true(
431 (ret == -EALREADY),
432 "mbox_set_enabled_dt(enabled_tx_channel, true) shall return -EALREADY (-120)"
433 " got unexpected %d",
434 ret
435 );
436
437 /* Cleanup - disable mbox channel */
438 ret = mbox_set_enabled_dt(&rx_channel, false);
439 zassert_true(
440 (ret == 0),
441 "mbox_set_enabled_dt(enabled_tx_channel, false) shall return 0"
442 " got unexpected %d",
443 ret
444 );
445 }
446
447 /**
448 * @brief mbox_set_enabled_dt() - Dsiable already disabled channel shall fail
449 *
450 * Confirm that mbox_set_enabled_dt() returns
451 * -EALREADY when user tries to disable already disabled RX mbox channel.
452 *
453 */
ZTEST(mbox_error_cases,test_05d_mbox_set_disable_on_already_disabled_rx_channel)454 ZTEST(mbox_error_cases, test_05d_mbox_set_disable_on_already_disabled_rx_channel)
455 {
456 const struct mbox_dt_spec rx_channel =
457 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_valid);
458 int ret;
459
460 /* The user must take care of installing a proper callback
461 * on the channel before enabling it.
462 */
463 ret = mbox_register_callback_dt(&rx_channel, dummy_callback, NULL);
464 zassert_true(
465 (ret == 0),
466 "mbox_register_callback(tx_channel) shall return 0"
467 " got unexpected %d",
468 ret
469 );
470
471 ret = mbox_set_enabled_dt(&rx_channel, true);
472 zassert_true(
473 (ret == 0),
474 "mbox_set_enabled_dt(tx_channel, true) shall return 0"
475 " got unexpected %d",
476 ret
477 );
478
479 ret = mbox_set_enabled_dt(&rx_channel, false);
480 zassert_true(
481 (ret == 0),
482 "mbox_set_enabled_dt(enabled_tx_channel, false) shall return 0"
483 " got unexpected %d",
484 ret
485 );
486
487 ret = mbox_set_enabled_dt(&rx_channel, false);
488 zassert_true(
489 (ret == -EALREADY),
490 "mbox_set_enabled_dt(disabled_tx_channel, false) shall return -EALREADY (-120)"
491 " got unexpected %d",
492 ret
493 );
494 }
495
496 /**
497 * @brief mbox_max_channels_get_dt() functional test
498 *
499 * Confirm that mbox_max_channels_get_dt() returns
500 * >0 Maximum possible number of supported channels on success
501 * (No matter if channel is valid or incorrect.)
502 *
503 */
ZTEST(mbox_error_cases,test_06_mbox_max_channels_get_functional)504 ZTEST(mbox_error_cases, test_06_mbox_max_channels_get_functional)
505 {
506 const struct mbox_dt_spec tx_channel =
507 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_valid);
508 const struct mbox_dt_spec tx_channel_incorrect =
509 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), remote_incorrect);
510 const struct mbox_dt_spec rx_channel =
511 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_valid);
512 const struct mbox_dt_spec rx_channel_incorrect =
513 MBOX_DT_SPEC_GET(DT_PATH(mbox_consumer), local_incorrect);
514 int ret1, ret2;
515
516 ret1 = mbox_max_channels_get_dt(&tx_channel);
517 TC_PRINT("mbox_max_channels_get_dt(tx_channel): %d\n", ret1);
518 zassert_true(
519 (ret1 > 0),
520 "mbox_max_channels_get_dt(tx_channel) shall return value greater than 0"
521 " got unexpected %d",
522 ret1
523 );
524
525 ret2 = mbox_max_channels_get_dt(&tx_channel_incorrect);
526 TC_PRINT("mbox_max_channels_get_dt(tx_channel_incorrect): %d\n", ret2);
527 zassert_true(
528 (ret2 > 0),
529 "mbox_max_channels_get_dt(tx_channel_incorrect) shall return value greater than 0"
530 " got unexpected %d",
531 ret2
532 );
533
534 zassert_true(
535 (ret1 == ret2),
536 "mbox_max_channels_get_dt() shall return same value disregarding channel No."
537 " got unexpected %d and %d",
538 ret1,
539 ret2
540 );
541
542 ret1 = mbox_max_channels_get_dt(&rx_channel);
543 TC_PRINT("mbox_max_channels_get_dt(rx_channel): %d\n", ret1);
544 zassert_true(
545 (ret1 > 0),
546 "mbox_max_channels_get_dt(rx_channel) shall return value greater than 0"
547 " got unexpected %d",
548 ret1
549 );
550
551 ret2 = mbox_max_channels_get_dt(&rx_channel_incorrect);
552 TC_PRINT("mbox_max_channels_get_dt(rx_channel_incorrect): %d\n", ret2);
553 zassert_true(
554 (ret2 > 0),
555 "mbox_max_channels_get_dt(rx_channel_incorrect) shall return value greater than 0"
556 " got unexpected %d",
557 ret2
558 );
559
560 zassert_true(
561 (ret1 == ret2),
562 "mbox_max_channels_get_dt() shall return same value disregarding channel No."
563 " got unexpected %d and %d",
564 ret1,
565 ret2
566 );
567 }
568
suite_setup(void)569 static void *suite_setup(void)
570 {
571 TC_PRINT("Test executed on %s\n", CONFIG_BOARD_TARGET);
572 TC_PRINT("===================================================================\n");
573
574 return NULL;
575 }
576
577 ZTEST_SUITE(mbox_error_cases, NULL, suite_setup, NULL, NULL, NULL);
578