1 /***************************************************************************/ /**
2  * @file
3  * @brief
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2024 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 
32 #ifndef _SL_RSI_UTILITY_H_
33 #define _SL_RSI_UTILITY_H_
34 
35 #include <stdint.h>
36 #include <string.h>
37 #include <stdbool.h>
38 #include "sl_status.h"
39 #include "sl_constants.h"
40 #include "sl_wifi_constants.h"
41 #include "sl_si91x_host_interface.h"
42 #include "sl_si91x_protocol_types.h"
43 #include "sl_utility.h"
44 #include "sl_si91x_driver.h"
45 #include "sl_wifi_device.h"
46 #include "sl_si91x_types.h"
47 
48 //! @cond Doxygen_Suppress
49 
50 /// Low Transmit Power Threshold for Wi-Fi.
51 #define SI91X_LOW_TRANSMIT_POWER_THRESHOLD 6
52 
53 /// Medium Transmit Power Threshold for Wi-Fi.
54 #define SI91X_MEDIUM_TRANSMIT_POWER_THRESHOLD 4
55 
56 /**
57  * Stack size of the event handler thread that processes all Wi-Fi and networking callbacks.
58  * This value can be overridden by defining a new value for SL_SI91X_EVENT_HANDLER_STACK_SIZE in your project or
59  * adding -DSL_SI91X_EVENT_HANDLER_STACK_SIZE=<new value> to your compiler command line options.
60  */
61 #ifndef SL_SI91X_EVENT_HANDLER_STACK_SIZE
62 #define SL_SI91X_EVENT_HANDLER_STACK_SIZE 1536
63 #endif
64 typedef bool (*sli_si91x_wifi_buffer_comparator)(const sl_wifi_buffer_t *buffer, const void *userdata);
65 
66 typedef struct {
67   sl_wifi_performance_profile_t wifi_performance_profile;
68   sl_bt_performance_profile_t bt_performance_profile;
69   sl_si91x_coex_mode_t coex_mode;
70 } sli_si91x_performance_profile_t;
71 
72 /// Efuse data information
73 typedef union {
74   uint8_t mfg_sw_version; ///< Manufacturing PTE software version
75   uint16_t pte_crc;       ///< PTE CRC value
76 } sl_si91x_efuse_data_t;
77 
78 typedef uint32_t sl_si91x_host_timestamp_t;
79 
80 void sli_handle_wifi_beacon(sl_si91x_packet_t *packet);
81 sl_status_t sli_wifi_get_stored_scan_results(sl_wifi_interface_t interface,
82                                              sl_wifi_extended_scan_result_parameters_t *extended_scan_parameters);
83 void sli_wifi_flush_scan_results_database(void);
84 
85 typedef void (*sl_si91x_host_atomic_action_function_t)(void *user_data);
86 typedef uint8_t (*sl_si91x_compare_function_t)(sl_wifi_buffer_t *node, void *user_data);
87 typedef void (*sl_si91x_node_free_function_t)(sl_wifi_buffer_t *node);
88 
89 /* Indicates the current performance profile */
90 extern sl_si91x_performance_profile_t current_performance_profile;
91 extern volatile uint32_t tx_command_queues_status;
92 extern volatile uint32_t tx_socket_command_queues_status;
93 extern volatile uint32_t tx_socket_data_queues_status;
94 extern volatile uint32_t tx_generic_socket_data_queues_status;
95 
96 extern volatile uint32_t tx_command_queues_command_in_flight_status;
97 extern volatile uint8_t tx_socket_command_command_in_flight_queues_status;
98 
99 /* Function converts NWP client info to SDK client info */
100 sl_status_t convert_si91x_wifi_client_info(sl_wifi_client_info_response_t *client_info_response,
101                                            const sl_si91x_client_info_response *sl_si91x_client_info_response);
102 
103 /* Function converts NWP events to SDK events */
104 sl_wifi_event_t convert_si91x_event_to_sl_wifi_event(rsi_wlan_cmd_response_t command, uint16_t frame_status);
105 
106 /* Function used to update the variable that stores the wifi rate */
107 sl_status_t save_sl_wifi_rate(sl_wifi_rate_t transfer_rate);
108 
109 /* Function used to retrieve the wifi rate */
110 sl_status_t get_saved_sl_wifi_rate(sl_wifi_rate_t *transfer_rate);
111 
112 /* Function used to set wifi rate to default value of 1 Mbps */
113 void reset_sl_wifi_rate();
114 
115 /* Function used to retrieve protocol and transfer rate */
116 sl_status_t get_rate_protocol_and_data_rate(const uint8_t data_rate,
117                                             sl_wifi_rate_protocol_t *rate_protocol,
118                                             sl_wifi_rate_t *transfer_rate);
119 
120 /* Function used to update the access point configuration */
121 sl_status_t save_ap_configuration(const sl_wifi_ap_configuration_t *wifi_ap_configuration);
122 
123 /* Function used to retrieve the access point configuration */
124 sl_status_t get_saved_ap_configuration(sl_wifi_ap_configuration_t *wifi_ap_confuguration);
125 
126 /* Function used to destroy the current access point configuration */
127 void reset_ap_configuration();
128 
129 /* Function used to set whether tcp auto close is enabled or disabled */
130 void save_tcp_auto_close_choice(bool is_tcp_auto_close_enabled);
131 
132 /* Function used to check whether tcp auto close is enabled or disabled */
133 bool is_tcp_auto_close_enabled();
134 void sli_si91x_save_tcp_ip_total_config_select_request(uint8_t tcp_ip_total_select);
135 uint8_t sli_si91x_get_tcp_ip_total_config_select_request();
136 
137 /* Function used to set whether card ready is required or not */
138 void set_card_ready_required(bool card_ready_required);
139 
140 /* Function used to check whether card ready is required or not */
141 bool get_card_ready_required();
142 
143 /* Function used to set the maximum transmission power */
144 void save_max_tx_power(uint8_t max_scan_tx_power, uint8_t max_join_tx_power);
145 
146 /* Function used to get maximum transmission power */
147 sl_wifi_max_tx_power_t get_max_tx_power();
148 
149 /* Function used to set maximum transmission power to default value(31 dBm) */
150 void reset_max_tx_power();
151 
152 /* Function used to set the current performance profile */
153 void save_wifi_current_performance_profile(const sl_wifi_performance_profile_t *profile);
154 
155 /* Function used to get current wifi performance profile */
156 void get_wifi_current_performance_profile(sl_wifi_performance_profile_t *profile);
157 
158 /* Function used to set the bluetooth performance profile */
159 void save_bt_current_performance_profile(const sl_bt_performance_profile_t *profile);
160 
161 /* Function used to retrieve bluetooth performance profile */
162 void get_bt_current_performance_profile(sl_bt_performance_profile_t *profile);
163 
164 /* Function used to retrieve the coex performance profile */
165 void get_coex_performance_profile(sl_si91x_performance_profile_t *profile);
166 
167 /* Function used to zero out the coex performance profile */
168 void reset_coex_current_performance_profile(void);
169 
170 /* Function used to update the boot configuration */
171 void save_boot_configuration(const sl_si91x_boot_configuration_t *boot_configuration);
172 
173 /* Function used to retrieve the boot configuration */
174 void get_saved_boot_configuration(sl_si91x_boot_configuration_t *boot_configuration);
175 
176 /* Function used to update the coex mode */
177 void save_coex_mode(sl_si91x_coex_mode_t coex_mode);
178 
179 /* Function used to retrieve the coex mode */
180 sl_si91x_coex_mode_t get_coex_mode(void);
181 
182 /* Function converts SDK encryption mode to NWP supported mode */
183 sl_status_t convert_sl_wifi_to_sl_si91x_encryption(sl_wifi_encryption_t encryption_mode, uint8_t *encryption_request);
184 
185 /***************************************************************************/ /**
186  * @brief
187  *   Initializes new task register index for storing firmware status.
188  *
189  * @details
190  *   This function sets up the task register index to store the firmware status in thread-specific storage.
191  *   For all the threads at this index of the thread local array firmware status will be stored.
192  *
193  * @return
194  *   sl_status_t. See [Status Codes](https://docs.silabs.com/gecko-platform/latest/platform-common/status) and [Additional Status Codes](../wiseconnect-api-reference-guide-err-codes/sl-additional-status-errors) for details.
195  ******************************************************************************/
196 sl_status_t sli_fw_status_storage_index_init(void);
197 
198 /***************************************************************************/ /**
199  * @brief
200  *   Get the Efuse Data content from flash.
201  * @pre Pre-conditions:
202  * -
203  *   @ref sl_wifi_init should be called before this API.
204  * @param[out] efuse_data
205  *   @ref sl_si91x_efuse_data_t object that contains the Manufacturing software version.
206  *   efuse_data_type which holds the type of efuse data to be read.
207  * @return
208  *   sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
209  * @note
210  *   This API is not supported in the current release.
211  ******************************************************************************/
212 sl_status_t sl_si91x_get_flash_efuse_data(sl_si91x_efuse_data_t *efuse_data, uint8_t efuse_data_type);
213 
214 /***************************************************************************/ /**
215  * @brief
216  *   Get the Efuse Data content from driver context.
217  * @pre Pre-conditions:
218  * -
219  *   @ref sl_wifi_init should be called before this API.
220  * @param[out] efuse_data
221  *   @ref sl_si91x_efuse_data_t object that contains the Manufacturing software version.
222  * @return
223  *   sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
224  ******************************************************************************/
225 void sl_si91x_get_efuse_data(sl_si91x_efuse_data_t *efuse_data);
226 
227 /***************************************************************************/ /**
228  * @brief
229  *   Set the Efuse Data content in driver context.
230  * @pre Pre-conditions:
231  * -
232  *   @ref sl_wifi_init should be called before this API.
233  * @param[out] efuse_data
234  *   @ref sl_si91x_efuse_data_t object that contains the Manufacturing software version.
235  * @return
236  *   sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
237  ******************************************************************************/
238 void sl_si91x_set_efuse_data(const sl_si91x_efuse_data_t *efuse_data);
239 
240 /**
241  * A utility function to convert dBm value to si91x specific power value
242  * @param wifi_max_tx_power which holds the join power value with dBm as units.
243  * @return si91x power level
244  */
convert_dbm_to_si91x_power_level(sl_wifi_max_tx_power_t wifi_max_tx_power)245 static inline uint8_t convert_dbm_to_si91x_power_level(sl_wifi_max_tx_power_t wifi_max_tx_power)
246 {
247   uint8_t power_value_in_dBm = wifi_max_tx_power.join_tx_power;
248   if (power_value_in_dBm >= SI91X_LOW_TRANSMIT_POWER_THRESHOLD) {
249     return SL_SI91X_LOW_POWER_LEVEL;
250   } else if (power_value_in_dBm >= SI91X_MEDIUM_TRANSMIT_POWER_THRESHOLD) {
251     return SL_SI91X_MEDIUM_POWER_LEVEL;
252   } else {
253     return SL_SI91X_HIGH_POWER_LEVEL;
254   }
255 }
256 
257 sl_status_t sl_si91x_platform_init(void);
258 sl_status_t sl_si91x_platform_deinit(void);
259 
260 // Event API
261 /* Function used to set specified flags for event */
262 void sli_si91x_set_event(uint32_t event_mask);
263 void sl_si91x_host_set_bus_event(uint32_t event_mask);
264 
265 /* Function used to set specified flags for async event */
266 void sl_si91x_host_set_async_event(uint32_t event_mask);
267 
268 uint32_t sli_si91x_wait_for_event(uint32_t event_mask, uint32_t timeout);
269 uint32_t si91x_host_wait_for_bus_event(uint32_t event_mask, uint32_t timeout);
270 
271 /* Function used to clear flags for specific event */
272 uint32_t sli_si91x_clear_event(uint32_t event_mask);
273 
274 /* Function to send the requested Wi-Fi and BT/BLE performance profile to firmware */
275 sl_status_t sli_si91x_send_power_save_request(const sl_wifi_performance_profile_t *wifi_profile,
276                                               const sl_bt_performance_profile_t *bt_profile);
277 
278 sl_status_t sl_si91x_host_init_buffer_manager(const sl_wifi_buffer_configuration_t *config);
279 sl_status_t sl_si91x_host_deinit_buffer_manager(void);
280 
281 /* Function used to allocate memory */
282 sl_status_t sl_si91x_host_allocate_buffer(sl_wifi_buffer_t **buffer,
283                                           sl_wifi_buffer_type_t type,
284                                           uint32_t buffer_size,
285                                           uint32_t wait_duration_ms);
286 
287 /* Function used to obtain pointer to a specified location in the buffer */
288 void *sl_si91x_host_get_buffer_data(sl_wifi_buffer_t *buffer, uint16_t offset, uint16_t *data_length);
289 
290 /* Function used to deallocate the memory associated with buffer */
291 void sl_si91x_host_free_buffer(sl_wifi_buffer_t *buffer);
292 
293 /* Function enqueues response into corresponding response queue */
294 sl_status_t sli_si91x_add_to_queue(sl_si91x_buffer_queue_t *queue, sl_wifi_buffer_t *buffer);
295 
296 /* Function dequeues responses from Asynch response queues */
297 sl_status_t sli_si91x_remove_from_queue(sl_si91x_buffer_queue_t *queue, sl_wifi_buffer_t **buffer);
298 
299 /* Function used to flush the pending TX packets from the specified queue */
300 sl_status_t sli_si91x_flush_nodes_from_queue(sli_si91x_command_queue_t *queue,
301                                              sl_si91x_node_free_function_t node_free_function);
302 
303 /* Function used to remove the buffer from the specified queue by using comparator */
304 sl_status_t sli_si91x_remove_buffer_from_queue_by_comparator(sl_si91x_buffer_queue_t *queue,
305                                                              const void *user_data,
306                                                              sli_si91x_wifi_buffer_comparator comparator,
307                                                              sl_wifi_buffer_t **buffer);
308 
309 sl_status_t sli_si91x_flush_all_tx_wifi_queues(uint16_t frame_status);
310 
311 /* Function used to flush all the pending TX packets from the specified queue */
312 sl_status_t sli_si91x_flush_queue_based_on_type(sli_si91x_command_queue_t *queue,
313                                                 uint32_t event_mask,
314                                                 uint16_t frame_status,
315                                                 sl_si91x_compare_function_t compare_function,
316                                                 void *user_data);
317 
318 /* Function used to check whether queue is empty or not */
319 uint32_t sl_si91x_host_queue_status(sl_si91x_buffer_queue_t *queue);
320 
321 // These aren't host APIs. These should go into a wifi bus API header
322 /* Function used to set buffer pointer to point to specified memory address */
323 sl_status_t sl_si91x_bus_read_memory(uint32_t addr, uint16_t length, uint8_t *buffer);
324 
325 /* Function used to set specified memory address to point to buffer */
326 sl_status_t sl_si91x_bus_write_memory(uint32_t addr, uint16_t length, const uint8_t *buffer);
327 
328 /*==============================================*/
329 /**
330  * @brief       Send chunk of data from Host to Si91x using SPI slave mode.
331  * @param[in]   data_length   -  Actual data length to send
332  * @param[in]   buffer        - Pointer to data
333  * @return      sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
334  *
335  */
336 sl_status_t sli_si91x_bus_write_slave(uint32_t data_length, const uint8_t *buffer);
337 
338 /* Function used to read contents of the register */
339 sl_status_t sl_si91x_bus_read_register(uint8_t address, uint8_t register_size, uint16_t *output);
340 
341 /* Function used to write data into register */
342 sl_status_t sl_si91x_bus_write_register(uint8_t address, uint8_t register_size, uint16_t data);
343 
344 /* Function used to read frame */
345 sl_status_t sl_si91x_bus_read_frame(sl_wifi_buffer_t **buffer);
346 
347 /* Function used to write frames */
348 sl_status_t sl_si91x_bus_write_frame(sl_si91x_packet_t *packet, const uint8_t *payloadparam, uint16_t size_param);
349 
350 /* Function used to check the bus availability */
351 sl_status_t sl_si91x_bus_init();
352 
353 /* Function used to check the bus availability */
354 sl_status_t sl_si91x_bus_rx_irq_handler(void);
355 
356 /* Function used to check the bus availability */
357 void sl_si91x_bus_rx_done_handler(void);
358 
359 /*==============================================*/
360 /**
361  * @brief       Calculate crc for a given byte and accumulate crc.
362  * @param[in]   crc8_din   -  crc byte input
363  * @param[in]   crc8_state - accumulated crc
364  * @param[in]   end        - last byte crc
365  * @return      crc value
366  *
367  */
368 uint8_t sli_lmac_crc8_c(uint8_t crc8_din, uint8_t crc8_state, uint8_t end);
369 
370 /*==============================================*/
371 /**
372  * @brief      Calculate 6-bit hash value for given mac address.
373  * @param[in]  mac - pointer to mac address
374  * @return     6-bit Hash value
375  *
376  */
377 uint8_t sli_multicast_mac_hash(const uint8_t *mac);
378 
379 /*==============================================*/
380 /**
381  * @brief       Sends boot instructions to WiFi module
382  * @param[in]   uint8 type, type of the insruction to perform
383  * @param[in]   uint32 *data, pointer to data which is to be read/write
384  * @param[out]  none
385  * @return
386  *   sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
387  * @section description
388  * This API is used to send boot instructions to WiFi module.
389  **************************************************/
390 sl_status_t sl_si91x_boot_instruction(uint8_t type, uint16_t *data);
391 
392 /***************************************************************************/ /**
393  * @brief
394  *   The @ref sl_si91x_bus_enable_high_speed() should be called only if the SPI clock frequency is more than 25 MHz.
395  * @note
396  *   SPI initialization has to be done in low-speed mode only.
397  *   After device SPI is configured, this API is used for high-speed mode (>25 MHz).
398  *   In addition to this API, the following API sl_si91x_host_enable_high_speed_bus has to be ported by the user to implement the host clock switch.
399  * @return
400  *   sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
401  ******************************************************************************/
402 sl_status_t sl_si91x_bus_enable_high_speed();
403 
404 /* Function used to read the interrupt register */
405 sl_status_t sl_si91x_bus_read_interrupt_status(uint16_t *interrupt_status);
406 
407 /* Function used to block specified interrupts */
408 sl_status_t sl_si91x_bus_set_interrupt_mask(uint32_t mask);
409 
410 /* Function used to initialize SPI interface on ULP wakeup */
411 void sl_si91x_ulp_wakeup_init(void);
412 
413 /**
414  * @brief
415  *  Function used to obtain wifi credential type like EsAP,PMK,etc..
416  * @param id
417  *  Credential ID as identified by [sl_wifi_credential_id_t](../wiseconnect-api-reference-guide-wi-fi/sl-wifi-types#sl-wifi-credential-id-t).
418  * @param type
419  *  It specifies type of credential.
420  * @param cred
421  *  Pointer to store the wifi credential information of type [sl_wifi_credential_t](../wiseconnect-api-reference-guide-wi-fi/sl-wifi-credential-t)
422  * @return sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
423  */
424 sl_status_t sl_si91x_host_get_credentials(sl_wifi_credential_id_t id, uint8_t type, sl_wifi_credential_t *cred);
425 
426 sli_si91x_command_queue_t *sli_si91x_get_command_queue(sl_si91x_command_type_t type);
427 
428 bool sli_si91x_get_flash_command_status();
429 
430 void sli_si91x_update_flash_command_status(bool flag);
431 
432 bool sli_si91x_is_sdk_ok_to_sleep();
433 //! @endcond
434 
435 /**
436 * @addtogroup EXTERNAL_HOST_INTERFACE_FUNCTIONS
437 * @{
438 */
439 
440 /***************************************************************************/
441 /**
442  * @brief
443  *   Delay execution for a specified number of milliseconds.
444  *
445  * @details
446  *   This function introduces a delay for the specified amount of time in milliseconds. It uses the underlying OS
447  *   delay function (`osDelay`) to yield the CPU, allowing other tasks to execute during the delay period. This
448  *   ensures that the delay does not block the execution flow.
449  *
450  * @param[in] delay_milliseconds
451  *   The time delay in milliseconds.
452  *****************************************************************************/
453 void sl_si91x_host_delay_ms(uint32_t delay_milliseconds);
454 
455 /**
456  * @brief
457  *   Retrieves the current timestamp.
458  *
459  * @details
460  *   This function retrieves the current timestamp from the host system. The timestamp can be used for various purposes such as logging, time measurements, and synchronization.
461  *
462  * @return
463  *   The current timestamp of type sl_si91x_host_timestamp_t.
464  */
465 sl_si91x_host_timestamp_t sl_si91x_host_get_timestamp(void);
466 
467 /**
468  * @brief
469  *   Calculates the elapsed time since a given starting timestamp.
470  *
471  * @details
472  *   This function calculates the difference between the current timestamp and a provided starting timestamp. It is useful for measuring the time elapsed during operations.
473  *
474  * @param[in] starting_timestamp
475  *   The starting timestamp from which the elapsed time is calculated.
476  *
477  * @return
478  *   The elapsed time in milliseconds of type sl_si91x_host_timestamp_t.
479  */
480 sl_si91x_host_timestamp_t sl_si91x_host_elapsed_time(uint32_t starting_timestamp);
481 
482 /**
483  * @brief
484  *   Checks if the device is initialized.
485  *
486  * @details
487  *   This function verifies whether the device has been properly initialized. It is typically used to ensure that the device is ready for operation before performing any further actions.
488  *
489  * @return
490  *   Returns `true` if the device is initialized, `false` otherwise.
491  */
492 bool sl_si91x_is_device_initialized(void);
493 
494 /** @} */
495 #ifdef SLI_SI91X_OFFLOAD_NETWORK_STACK
496 sl_status_t sli_si91x_flush_all_socket_command_queues(uint16_t frame_status, uint8_t vap_id);
497 
498 sl_status_t sli_si91x_flush_socket_command_queues_based_on_queue_type(uint8_t index, uint16_t frame_status);
499 
500 sl_status_t sli_si91x_flush_all_socket_data_queues(uint8_t vap_id);
501 
502 sl_status_t sli_si91x_flush_socket_data_queues_based_on_queue_type(uint8_t index);
503 #endif
504 
505 /**
506  * @brief Flushes all packets from the specified data transmission queue.
507  * @details This function removes all packets from the provided transmission queue (`tx_data_queue`) and frees the associated memory. It ensures thread-safe operation by preventing race conditions during the process.
508  *
509  * @param[in, out] tx_data_queue Pointer to the transmission data queue to be flushed.
510  *                               The queue will be reset to an empty state after the function completes.
511  *
512  * @return
513  * - `SL_STATUS_OK`: The operation was successful, and the queue has been flushed.
514  * - `SL_STATUS_FAIL`: The provided queue pointer is NULL.
515  *
516  * @note
517  * - This function is typically used to clear transmission buffers in scenarios such as error recovery or reinitialization.
518  * - The function uses atomic operations to ensure that the queue is safely manipulated in multi-threaded environments.
519  * - The function resets the queue to an empty state after flushing all packets.
520  */
521 sl_status_t sli_si91x_flush_generic_data_queues(sl_si91x_buffer_queue_t *tx_data_queue);
522 
523 #endif // _SL_RSI_UTILITY_H_
524