1 /***************************************************************************/ /**
2  * @file
3  * @brief
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 #pragma once
31 #include "sl_si91x_types.h"
32 #include "sl_wifi_device.h"
33 #include "sl_additional_status.h"
34 
35 /******************************************************************************
36  * A utility function to extract firmware status from RX packet.
37  * The extracted firmware status can be given to convert_and_save_firmware_status() to get sl_status equivalent.
38  * @param packet packet that contains the frame status which needs to be extracted.
39  * @return  frame status
40  *****************************************************************************/
get_si91x_frame_status(const sl_si91x_packet_t * packet)41 static inline uint16_t get_si91x_frame_status(const sl_si91x_packet_t *packet)
42 {
43   return (uint16_t)(packet->desc[12] + (packet->desc[13] << 8));
44 }
45 
46 /******************************************************************************
47  * @brief
48  *   A utility function that converts frame status sent by firmware to sl_status_t and stores in thread local storage of caller thread.
49  * @param[in] si91x_firmware_status
50  *   si91x_firmware_status that needs to be converted to sl_status_t.
51  * @return
52  *   sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
53  *****************************************************************************/
convert_and_save_firmware_status(uint16_t si91x_firmware_status)54 static inline sl_status_t convert_and_save_firmware_status(uint16_t si91x_firmware_status)
55 {
56   sl_status_t converted_firmware_status = (si91x_firmware_status == SL_STATUS_OK) ? SL_STATUS_OK
57                                                                                   : (si91x_firmware_status | BIT(16));
58   return converted_firmware_status;
59 }
60 /******************************************************************************
61  * @brief
62  *   A utility function that converts si91x_status_t to sl_status_t
63  * @param[in] si91x_status
64  *   si91x_status that needs to be converted to sl_status_t.
65  * @return
66  *   sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
67  *****************************************************************************/
convert_si91x_status_to_sl_status(si91x_status_t si91x_status)68 static inline sl_status_t convert_si91x_status_to_sl_status(si91x_status_t si91x_status)
69 {
70   switch (si91x_status) {
71     case RSI_ERROR_NONE:
72       return SL_STATUS_OK;
73     case RSI_ERROR_TIMEOUT:
74       return SL_STATUS_TIMEOUT;
75     case RSI_ERROR_INVALID_PARAM:
76       return SL_STATUS_INVALID_PARAMETER;
77     case RSI_ERROR_COMMAND_GIVEN_IN_WRONG_STATE:
78       return SL_STATUS_INVALID_STATE;
79     case RSI_ERROR_PKT_ALLOCATION_FAILURE:
80       return SL_STATUS_ALLOCATION_FAILED;
81     case RSI_ERROR_COMMAND_NOT_SUPPORTED:
82       return SL_STATUS_NOT_SUPPORTED;
83     case RSI_ERROR_INSUFFICIENT_BUFFER:
84       return SL_STATUS_NO_MORE_RESOURCE;
85     case RSI_ERROR_IN_OS_OPERATION:
86       return SL_STATUS_OS_OPERATION_FAILURE;
87     case RSI_ERROR_BOOTUP_OPTIONS_NOT_SAVED:
88       return SL_STATUS_BOOTUP_OPTIONS_NOT_SAVED;
89     case RSI_ERROR_BOOTLOADER_VERSION_NOT_MATCHING:
90       return SL_STATUS_BOOTLOADER_VERSION_MISMATCH;
91     case RSI_ERROR_WAITING_FOR_BOARD_READY:
92       return SL_STATUS_WAITING_FOR_BOARD_READY;
93     case RSI_ERROR_VALID_FIRMWARE_NOT_PRESENT:
94       return SL_STATUS_VALID_FIRMWARE_NOT_PRESENT;
95     case RSI_ERROR_INVALID_OPTION:
96       return SL_STATUS_INVALID_OPTION;
97     case RSI_ERROR_SPI_BUSY:
98       return SL_STATUS_SPI_BUSY;
99     case RSI_ERROR_CARD_READY_TIMEOUT:
100       return SL_STATUS_CARD_READY_TIMEOUT;
101     case RSI_ERROR_FW_LOAD_OR_UPGRADE_TIMEOUT:
102       return SL_STATUS_FW_LOAD_OR_UPGRADE_TIMEOUT;
103     default:
104       return SL_STATUS_FAIL;
105   }
106 }
107 
108 /**
109  * @brief Atomically append a given buffer to the end of a buffer queue.
110  *
111  * This function appends a buffer to the end of a specified buffer queue in an atomic operation,
112  * ensuring thread safety during the append operation.
113  *
114  * @param[in] queue Pointer to the destination buffer queue where the buffer will be appended.
115  * @param[in] buffer Pointer to the buffer that is to be appended to the queue.
116  */
117 void sli_si91x_append_to_buffer_queue(sl_si91x_buffer_queue_t *queue, sl_wifi_buffer_t *buffer);
118 
119 /**
120  * @brief Atomically remove the head buffer from a buffer queue.
121  *
122  * This function removes the buffer at the head of the specified buffer queue in an atomic operation,
123  * ensuring thread safety during the removal. The removed buffer is then passed back through a pointer
124  * to the caller.
125  *
126  * @param[in] queue Pointer to the source buffer queue from which the head buffer will be removed.
127  * @param[out] buffer Pointer to a pointer of sl_wifi_buffer_t where the removed buffer's address will be stored.
128  * @return sl_status_t Returns the status of the operation. A value of 0 (SL_STATUS_OK) indicates success.
129  *                     Other values indicate failure. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
130  */
131 sl_status_t sli_si91x_pop_from_buffer_queue(sl_si91x_buffer_queue_t *queue, sl_wifi_buffer_t **buffer);
132 
133 /**
134  * @brief
135  *   Allocate a buffer to send a command
136  * @param[out] host_buffer
137  *   Destination buffer object
138  * @param[out] buffer
139  *   Start of the internal buffer data
140  * @param[in] requested_buffer_size
141  *   Requested buffer size
142  * @param[in] wait_duration_ms
143  *   Duration to wait for buffer to become available
144  * @return sl_status_t Returns the status of the operation. A value of 0 (SL_STATUS_OK) indicates success.
145  *                     Other values indicate failure. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
146  */
147 sl_status_t sli_si91x_allocate_command_buffer(sl_wifi_buffer_t **host_buffer,
148                                               void **buffer,
149                                               uint32_t requested_buffer_size,
150                                               uint32_t wait_duration_ms);
151 
152 /******************************************************************************
153  * @brief
154  *   Check if buffer queue is empty
155  * @param[in] queue
156  *   Requested buffer size
157  * @return
158  *   true if empty; false if not empty.
159  *****************************************************************************/
sli_si91x_buffer_queue_empty(sl_si91x_buffer_queue_t * queue)160 static inline bool sli_si91x_buffer_queue_empty(sl_si91x_buffer_queue_t *queue)
161 {
162   return (queue->head == NULL);
163 }
164