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/logging/log.h>
9 
10 #include <openthread/platform/messagepool.h>
11 
12 #define LOG_MODULE_NAME net_otPlat_messagepool
13 #define LOG_LEVEL       CONFIG_OPENTHREAD_LOG_LEVEL
14 
15 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
16 
17 #define BUF_TIMEOUT K_MSEC(50)
18 
19 #define MESSAGE_POOL_SIZE                                                                          \
20 	(CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS * CONFIG_OPENTHREAD_MESSAGE_BUFFER_SIZE)
21 #define MAX_ALIGNMENT __alignof__(z_max_align_t)
22 
23 BUILD_ASSERT(CONFIG_OPENTHREAD_MESSAGE_BUFFER_SIZE % MAX_ALIGNMENT == 0,
24 	     "Invalid message buffer size");
25 
26 static struct k_mem_slab message_pool;
__aligned(MAX_ALIGNMENT)27 __aligned(MAX_ALIGNMENT) static uint8_t message_pool_buffer[MESSAGE_POOL_SIZE];
28 
29 void otPlatMessagePoolInit(otInstance *aInstance, uint16_t aMinNumFreeBuffers, size_t aBufferSize)
30 {
31 	ARG_UNUSED(aInstance);
32 
33 	__ASSERT(aBufferSize == CONFIG_OPENTHREAD_MESSAGE_BUFFER_SIZE,
34 		 "Message buffer size does not match configuration");
35 
36 	if (aMinNumFreeBuffers > CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS) {
37 		LOG_WRN("Minimum number of free buffers (%d) is greater than number of allocated "
38 			"buffers (%d)",
39 			aMinNumFreeBuffers, CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS);
40 	}
41 
42 	if (k_mem_slab_init(&message_pool, message_pool_buffer, aBufferSize,
43 			    CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS) != 0) {
44 		__ASSERT(false, "Failed to initialize message pool");
45 	}
46 }
47 
otPlatMessagePoolNew(otInstance * aInstance)48 otMessageBuffer *otPlatMessagePoolNew(otInstance *aInstance)
49 {
50 	ARG_UNUSED(aInstance);
51 
52 	otMessageBuffer *buffer;
53 
54 	if (k_mem_slab_alloc(&message_pool, (void **)&buffer, BUF_TIMEOUT) != 0) {
55 		LOG_ERR("Failed to allocate message buffer");
56 		return NULL;
57 	}
58 
59 	buffer->mNext = NULL;
60 	return buffer;
61 }
62 
otPlatMessagePoolFree(otInstance * aInstance,otMessageBuffer * aBuffer)63 void otPlatMessagePoolFree(otInstance *aInstance, otMessageBuffer *aBuffer)
64 {
65 	ARG_UNUSED(aInstance);
66 
67 	k_mem_slab_free(&message_pool, (void *)aBuffer);
68 }
69