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