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 #include "sl_wifi.h"
31 #include "sl_wifi_types.h"
32 #include "sl_wifi_device.h"
33 #include "sl_si91x_host_interface.h"
34 #include "sl_si91x_status.h"
35 #include "sl_si91x_types.h"
36 #include "sl_si91x_protocol_types.h"
37 #include "sl_si91x_driver.h"
38 #include "sl_rsi_utility.h"
39 #if defined(SLI_SI91X_SOCKETS)
40 #include "sl_si91x_socket_utility.h"
41 #endif
42 #include <stdint.h>
43 #include <string.h>
44
45 #ifndef SL_NCP_DEFAULT_COMMAND_WAIT_TIME
46 #define SL_NCP_DEFAULT_COMMAND_WAIT_TIME 3000
47 #endif
48
49 #ifdef SL_SI91X_SIDE_BAND_CRYPTO
50 #include "sl_si91x_driver.h"
51 #include "rsi_m4.h"
52 extern rsi_m4ta_desc_t crypto_desc[2];
53 #endif
54
55 #ifdef SLI_SI91X_MCU_INTERFACE
56 #include "rsi_wisemcu_hardware_setup.h"
57 #endif
58
59 #ifdef SLI_SI91X_OFFLOAD_NETWORK_STACK
60 #include "sl_net_si91x_integration_handler.h"
61 #else
62
63 // This macro defines a handler for cleaning up resources.
64 #define SLI_NETWORK_CLEANUP_HANDLER() \
65 { \
66 }
67 #endif
68 // Enterprise configuration command parameters
69 /*=======================================================================*/
70
71 // Enterprise method ,should be one of among TLS, TTLS, FAST or PEAP
72
73 #define SL_EAP_TLS_METHOD "TLS"
74 #define SL_EAP_TTLS_METHOD "TTLS"
75 #define SL_EAP_FAST_METHOD "FAST"
76 #define SL_EAP_PEAP_METHOD "PEAP"
77 #define SL_EAP_LEAP_METHOD "LEAP"
78
79 // This parameter is used to configure the module in Enterprise security mode
80 #define SL_EAP_INNER_METHOD "\"auth=MSCHAPV2\""
81
82 // Private Key Password is required for encrypted private key, format is like "\"12345678\""
83 #define SL_DEFAULT_PRIVATE_KEY_PASSWORD ""
84
85 #define JOIN_TIMEOUT 8000
86
87 #define ALWAYS_ROAM 1
88 #define NEVER_ROAM 0
89 #define MAX_FLOW_ID 7
90 #define MAX_WAKE_INTERVAL_EXPONENT 31
91 #define MAX_WAKE_INTERVAL_EXPONENT_TOLERANCE 31
92 #define MAX_WAKE_DURATION_UNIT 1
93 #define MAX_TWT_RETRY_LIMIT 15
94 #define MIN_TWT_RETRY_INTERVAL 5
95 #define MAX_TWT_REQ_TYPE 2
96 #define REQUEST_TWT 0
97 #define SUGGEST_TWT 1
98 #define DEMAND_TWT 1
99 #define TWT_WAKE_DURATION_UNIT_1024TU 1024
100 #define TWT_WAKE_DURATION_UNIT_256TU 256
101 #define DEVICE_AVERAGE_THROUGHPUT 20000
102 #define MAX_TX_AND_RX_LATENCY_LIMIT 21600000
103 #define MAX_TWT_SUSPEND_DURATION 0x5265c00
104 #define ABSOLUTE_POWER_VALUE_TOGGLE 0x80
105 #define PASSIVE_SCAN_ENABLE BIT(7)
106 #define LP_CHAIN_ENABLE BIT(6)
107 #define QUICK_SCAN_ENABLE 1
108 #define SCAN_RESULTS_TO_HOST 2
109 #define MAX_2_4G_CHANNEL 14
110
111 /*========================================================================*/
112 // 11ax params
113 /*========================================================================*/
114 #define NOMINAL_PE 2
115 #define DCM_ENABLE 0
116 #define LDPC_ENABLE 0
117 #define NG_CB_ENABLE 0
118 #define NG_CB_VALUES 0
119 #define UORA_ENABLE 0
120 #define TRIGGER_RESP_IND 0xF
121 #define IPPS_VALID_VALUE 0
122 #define TX_ONLY_ON_AP_TRIG 0
123 #define CONFIG_ER_SU 0 // 0 - NO ER_SU support, 1 - Use ER_SU rates along with Non_ER_SU rates, 2 - Use ER_SU rates only
124 #define SLI_SI91X_ENABLE_TWT_FEATURE 1
125 #define SLI_SI91X_DISABLE_SU_BEAMFORMEE_SUPPORT 0
126 /*=======================================================================*/
127 extern bool device_initialized;
128 extern bool bg_enabled;
129 extern bool interface_is_up[SL_WIFI_MAX_INTERFACE_INDEX];
130 extern sl_wifi_interface_t default_interface;
131 static sl_wifi_advanced_scan_configuration_t advanced_scan_configuration = { 0 };
132 static sl_wifi_advanced_client_configuration_t advanced_client_configuration = { 0 };
133 int32_t validate_datarate(sl_wifi_data_rate_t data_rate);
134 sl_status_t sl_wifi_get_associated_client_list(void *client_list_buffer, uint16_t buffer_length, uint32_t timeout);
135 static sl_wifi_client_info_response_t sli_si91x_client_info = { 0 };
136
fill_join_request_security_using_encryption(sl_wifi_encryption_t encryption_mode,uint8_t * security_type)137 static sl_status_t fill_join_request_security_using_encryption(sl_wifi_encryption_t encryption_mode,
138 uint8_t *security_type)
139 {
140 if (encryption_mode == SL_WIFI_CCMP_ENCRYPTION) {
141 *security_type |= BIT(7);
142 }
143 return SL_STATUS_OK;
144 }
145
get_configured_join_request(sl_wifi_interface_t module_interface,const void * configuration,sl_si91x_join_request_t * join_request)146 static sl_status_t get_configured_join_request(sl_wifi_interface_t module_interface,
147 const void *configuration,
148 sl_si91x_join_request_t *join_request)
149 {
150 SL_WIFI_ARGS_CHECK_NULL_POINTER(configuration);
151 SL_WIFI_ARGS_CHECK_NULL_POINTER(join_request);
152 sl_status_t status = SL_STATUS_OK;
153
154 if (module_interface & SL_WIFI_CLIENT_INTERFACE) {
155 // get join feature bitmap
156 status = sl_si91x_get_join_configuration(SL_WIFI_CLIENT_INTERFACE, &(join_request->join_feature_bitmap));
157 VERIFY_STATUS_AND_RETURN(status);
158
159 sl_wifi_client_configuration_t *client_configuration = (sl_wifi_client_configuration_t *)configuration;
160
161 // narrowing conversion from Enum of uint16 to uint8
162 get_saved_sl_wifi_rate(&join_request->data_rate);
163 memcpy(join_request->ssid, client_configuration->ssid.value, client_configuration->ssid.length);
164
165 join_request->ssid_len = client_configuration->ssid.length;
166 join_request->security_type = client_configuration->security;
167 if ((join_request->security_type == SL_WIFI_WPA3)
168 || (join_request->security_type == SL_WIFI_WPA3_ENTERPRISE)) { //check for WPA3 security
169 join_request->join_feature_bitmap |= SL_SI91X_JOIN_FEAT_MFP_CAPABLE_REQUIRED;
170 } else if ((join_request->security_type == SL_WIFI_WPA3_TRANSITION)
171 || join_request->security_type == SL_WIFI_WPA3_TRANSITION_ENTERPRISE) {
172 join_request->join_feature_bitmap &= ~(SL_SI91X_JOIN_FEAT_MFP_CAPABLE_REQUIRED);
173 join_request->join_feature_bitmap |= SL_SI91X_JOIN_FEAT_MFP_CAPABLE_ONLY;
174 } else if (join_request->security_type == SL_WIFI_WPA2 || join_request->security_type == SL_WIFI_WPA_WPA2_MIXED) {
175 join_request->join_feature_bitmap |= SL_SI91X_JOIN_FEAT_MFP_CAPABLE_ONLY;
176 }
177
178 fill_join_request_security_using_encryption(client_configuration->encryption, &(join_request->security_type));
179
180 join_request->vap_id = SL_SI91X_WIFI_CLIENT_VAP_ID; // For Station vap_id will be 0
181 join_request->listen_interval = sl_si91x_get_listen_interval();
182 memcpy(join_request->join_bssid, client_configuration->bssid.octet, sizeof(join_request->join_bssid));
183 } else if (module_interface & SL_WIFI_AP_INTERFACE) {
184 // get join feature bitmap
185 status = sl_si91x_get_join_configuration(SL_WIFI_AP_INTERFACE, &(join_request->join_feature_bitmap));
186 VERIFY_STATUS_AND_RETURN(status);
187
188 sl_wifi_ap_configuration_t *ap_configuration = (sl_wifi_ap_configuration_t *)configuration;
189
190 get_saved_sl_wifi_rate(&join_request->data_rate);
191 memcpy(join_request->ssid, ap_configuration->ssid.value, ap_configuration->ssid.length);
192
193 join_request->ssid_len = ap_configuration->ssid.length;
194 join_request->security_type = ap_configuration->security;
195 join_request->vap_id = 0;
196 if (join_request->security_type == SL_WIFI_WPA3) { //check for WPA3 security
197 join_request->join_feature_bitmap |= SL_SI91X_JOIN_FEAT_MFP_CAPABLE_REQUIRED;
198 } else if (join_request->security_type == SL_WIFI_WPA3_TRANSITION) { //check for WPA3 Tranisition security
199 join_request->join_feature_bitmap &= ~(SL_SI91X_JOIN_FEAT_MFP_CAPABLE_REQUIRED);
200 join_request->join_feature_bitmap |= SL_SI91X_JOIN_FEAT_MFP_CAPABLE_ONLY;
201 }
202
203 if (get_opermode() == SL_SI91X_CONCURRENT_MODE) {
204 join_request->vap_id = SL_SI91X_WIFI_AP_VAP_ID; // For Concurrent mode AP vap_id should be 1 else 0.
205 }
206 } else {
207 return SL_STATUS_FAIL;
208 }
209
210 sl_wifi_max_tx_power_t wifi_max_tx_power = get_max_tx_power();
211
212 /* Within the 1-byte 'power_level' variable, bit 0 and bit 1 are allocated for encoding power level thresholds(low, mid, high).
213 * The Most Significant Bit serves as an indicator for toggling between absolute power value representation.
214 * When the MSB is set, the 'power_level' variable encodes the absolute power value using bits 2 through 6. */
215 join_request->power_level = (wifi_max_tx_power.join_tx_power << 2) | ABSOLUTE_POWER_VALUE_TOGGLE;
216
217 return SL_STATUS_OK;
218 }
219
220 /***************************************************************************/ /**
221 * @brief
222 * to enable/disable ht capabilities
223 * @pre Pre-conditions:
224 * - @ref sl_wifi_init should be called before this API.
225 * @param[in] interface
226 * Wi-Fi Access Point interface as identified by @ref sl_wifi_interface_t
227 * @param[in] HtCaps
228 * HtCaps is identified by @ref sl_si91x_request_ap_high_throughput_capability_t
229 * @return
230 * sl_status_t. See https://docs.silabs.com/gecko-platform/latest/platform-common/status for details.
231 * @note
232 * Client interfaces are not supported.
233 ******************************************************************************/
sli_si91x_set_high_throughput_capability(sl_wifi_interface_t interface,sl_si91x_request_ap_high_throughput_capability_t HtCaps)234 static sl_status_t sli_si91x_set_high_throughput_capability(sl_wifi_interface_t interface,
235 sl_si91x_request_ap_high_throughput_capability_t HtCaps)
236 {
237 if (!device_initialized) {
238 return SL_STATUS_NOT_INITIALIZED;
239 }
240
241 if (interface & SL_WIFI_CLIENT_INTERFACE) {
242 return SL_STATUS_NOT_SUPPORTED;
243 }
244
245 sl_status_t status = SL_STATUS_OK;
246 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_HT_CAPABILITIES,
247 SI91X_WLAN_CMD,
248 &HtCaps,
249 sizeof(sl_si91x_request_ap_high_throughput_capability_t),
250 SL_SI91X_WAIT_FOR(30100),
251 NULL,
252 NULL);
253 VERIFY_STATUS_AND_RETURN(status);
254 return status;
255 }
256
sl_wifi_init(const sl_wifi_device_configuration_t * configuration,sl_wifi_device_context_t * device_context,sl_wifi_event_handler_t event_handler)257 sl_status_t sl_wifi_init(const sl_wifi_device_configuration_t *configuration,
258 sl_wifi_device_context_t *device_context,
259 sl_wifi_event_handler_t event_handler)
260 {
261 UNUSED_PARAMETER(device_context);
262 #ifdef SLI_SI91X_MCU_INTERFACE
263 #if defined(SLI_SI917)
264 sl_si91x_efuse_data_t efuse_data;
265 #endif
266 #endif
267 sl_status_t status = SL_STATUS_OK;
268 status = sl_si91x_driver_init(configuration, event_handler);
269 #ifdef SL_SI91X_SIDE_BAND_CRYPTO
270 if (status == SL_STATUS_OK) {
271 uint32_t crypto_desc_ptr = (uint32_t)crypto_desc;
272 uint32_t *desc_ptr = &crypto_desc_ptr;
273 status = sl_si91x_m4_ta_secure_handshake(SL_SI91X_ENABLE_SIDE_BAND, sizeof(uint32_t), (uint8_t *)desc_ptr, 0, NULL);
274 }
275 #endif
276 #ifdef SLI_SI91X_MCU_INTERFACE
277 #if defined(SLI_SI917)
278 if (status == SL_STATUS_OK) {
279 /*Getting PTE CRC value to distinguish firmware 17 and 18 boards.*/
280 sl_si91x_get_flash_efuse_data(&efuse_data, SL_SI91X_EFUSE_PTE_CRC);
281
282 /*PTE FW version check.*/
283 if (efuse_data.pte_crc == FIRMWARE_17_PTE_CRC_VALUE) {
284 /* Enable Higher PWM RO Frequency Mode for PMU for FW17 boards*/
285 RSI_IPMU_Set_Higher_Pwm_Ro_Frequency_Mode_to_PMU();
286 /* Set the RETN_LDO voltage to 0.8V for FW17 boards*/
287 RSI_IPMU_Retn_Voltage_To_Default();
288 }
289 }
290 #endif
291 #endif
292 return status;
293 }
294
sl_wifi_set_antenna(sl_wifi_interface_t interface,sl_wifi_antenna_t antenna)295 sl_status_t sl_wifi_set_antenna(sl_wifi_interface_t interface, sl_wifi_antenna_t antenna)
296 {
297 UNUSED_PARAMETER(interface);
298 sl_status_t status;
299 sl_si91x_antenna_select_t rsi_antenna = { 0 };
300
301 if (!device_initialized) {
302 return SL_STATUS_NOT_INITIALIZED;
303 }
304
305 if (!sl_wifi_is_interface_up(interface)) {
306 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
307 }
308
309 // Antenna type
310 rsi_antenna.antenna_value = (antenna == SL_WIFI_ANTENNA_EXTERNAL) ? SL_WIFI_SELECT_EXTERNAL_ANTENNA
311 : SL_WIFI_SELECT_INTERNAL_ANTENNA;
312
313 status = sl_si91x_driver_send_command(RSI_COMMON_REQ_ANTENNA_SELECT,
314 SI91X_COMMON_CMD,
315 &rsi_antenna,
316 sizeof(rsi_antenna),
317 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
318 NULL,
319 NULL);
320 VERIFY_STATUS_AND_RETURN(status);
321 return status;
322 }
323
sl_wifi_wait_for_scan_results(sl_wifi_scan_result_t ** scan_results,uint32_t max_scan_result_count)324 sl_status_t sl_wifi_wait_for_scan_results(sl_wifi_scan_result_t **scan_results, uint32_t max_scan_result_count)
325 {
326 UNUSED_PARAMETER(scan_results);
327 UNUSED_PARAMETER(max_scan_result_count);
328
329 #ifdef SI91x_ENABLE_WAIT_ON_RESULTS
330 if (!device_initialized) {
331 return SL_STATUS_NOT_INITIALIZED;
332 }
333 sl_status_t status;
334 sl_wifi_buffer_t *buffer;
335 sl_si91x_packet_t *packet;
336
337 status = sl_si91x_driver_wait_for_response(RSI_WLAN_RSP_SCAN, SL_SI91X_WAIT_FOR(3000));
338 VERIFY_STATUS_AND_RETURN(status);
339
340 status = sl_si91x_host_remove_from_queue(SI91X_WLAN_RESPONSE_QUEUE, &buffer);
341 VERIFY_STATUS_AND_RETURN(status);
342
343 packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
344 status = convert_and_save_firmware_status(get_si91x_frame_status(packet));
345 VERIFY_STATUS_AND_RETURN(status);
346
347 if (packet->command == RSI_WLAN_RSP_SCAN) {
348 *scan_results = (sl_wifi_scan_result_t *)malloc(packet->length);
349 if (scan_results == NULL) {
350 sl_si91x_host_free_buffer(buffer);
351 return SL_STATUS_ALLOCATION_FAILED;
352 }
353 memcpy(*scan_results, packet->data, packet->length);
354 }
355 sl_si91x_host_free_buffer(buffer);
356 #endif
357
358 return SL_STATUS_NOT_SUPPORTED;
359 }
360
sl_wifi_start_scan(sl_wifi_interface_t interface,const sl_wifi_ssid_t * optional_ssid,const sl_wifi_scan_configuration_t * configuration)361 sl_status_t sl_wifi_start_scan(sl_wifi_interface_t interface,
362 const sl_wifi_ssid_t *optional_ssid,
363 const sl_wifi_scan_configuration_t *configuration)
364 {
365 sl_status_t status = SL_STATUS_FAIL;
366
367 if (!device_initialized) {
368 return SL_STATUS_NOT_INITIALIZED;
369 }
370
371 if (!sl_wifi_is_interface_up(interface)) {
372 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
373 }
374
375 if (SL_WIFI_SCAN_TYPE_ADV_SCAN != configuration->type) {
376 sl_si91x_req_scan_t scan_request = { 0 };
377
378 //! copying SSID & length
379 if (optional_ssid != NULL) {
380 memcpy(scan_request.ssid, optional_ssid->value, optional_ssid->length);
381 }
382
383 if ((interface & SL_WIFI_2_4GHZ_INTERFACE) && (configuration->channel_bitmap_2g4 != 0xFFFF)) {
384 memcpy(&scan_request.channel_bit_map_2_4,
385 &configuration->channel_bitmap_2g4,
386 sizeof(scan_request.channel_bit_map_2_4));
387
388 uint16_t channel_bitmap = configuration->channel_bitmap_2g4;
389 // Set channel, if only one channel is selected in channel_bitmap
390 // if channel is 0, scan on all channels.
391 if ((channel_bitmap > 0) && (0 == (channel_bitmap & (channel_bitmap - 1)))) {
392 for (uint8_t channel = 1; channel <= MAX_2_4G_CHANNEL; channel++) {
393 if (BIT((channel - 1)) == channel_bitmap) {
394 scan_request.channel[0] = channel;
395 break;
396 }
397 }
398 }
399 }
400
401 if (configuration->type == SL_WIFI_SCAN_TYPE_PASSIVE) {
402 scan_request.pscan_bitmap[3] |= PASSIVE_SCAN_ENABLE;
403 }
404 if (configuration->lp_mode) {
405 scan_request.pscan_bitmap[3] |= LP_CHAIN_ENABLE;
406 }
407 sl_wifi_max_tx_power_t wifi_max_tx_power = get_max_tx_power();
408 // Within the 1-byte scan_feature_bimap variable, last 5 bits(bit 3 through bit 7) are allocated for
409 // encoding the transmit power during scan procedure.
410 scan_request.scan_feature_bitmap = (wifi_max_tx_power.scan_tx_power << 3);
411
412 // Enable Quick Scan, if SSID and channel are available
413 // Quick Scan is disabled, if channel is 0
414 if ((optional_ssid != NULL) && (scan_request.channel[0] != 0)) {
415 scan_request.scan_feature_bitmap |= QUICK_SCAN_ENABLE;
416 }
417
418 if (advanced_scan_configuration.active_channel_time != SL_WIFI_DEFAULT_ACTIVE_CHANNEL_SCAN_TIME) {
419 sl_status_t status = sl_si91x_configure_timeout(SL_SI91X_CHANNEL_ACTIVE_SCAN_TIMEOUT,
420 advanced_scan_configuration.active_channel_time);
421 VERIFY_STATUS_AND_RETURN(status);
422 }
423
424 if (SL_WIFI_SCAN_TYPE_EXTENDED == configuration->type) {
425 scan_request.scan_feature_bitmap |= SCAN_RESULTS_TO_HOST;
426 }
427 sli_wifi_flush_scan_results_database();
428
429 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_SCAN,
430 SI91X_WLAN_CMD,
431 &scan_request,
432 sizeof(scan_request),
433 SL_SI91X_RETURN_IMMEDIATELY,
434 NULL,
435 NULL);
436 } else {
437 sl_si91x_req_bg_scan_t scan_request = { 0 };
438
439 scan_request.bgscan_enable = SI91X_BG_SCAN_ENABLE;
440 scan_request.enable_instant_bgscan = advanced_scan_configuration.enable_instant_scan;
441 scan_request.passive_scan_duration = advanced_scan_configuration.passive_channel_time;
442 scan_request.active_scan_duration = advanced_scan_configuration.active_channel_time;
443 scan_request.bgscan_periodicity = (uint16_t)configuration->periodic_scan_interval;
444 scan_request.rssi_tolerance_threshold = (uint16_t)advanced_scan_configuration.trigger_level_change;
445 scan_request.bgscan_threshold = -1 * advanced_scan_configuration.trigger_level;
446 scan_request.multi_probe = advanced_scan_configuration.enable_multi_probe;
447
448 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_BG_SCAN,
449 SI91X_WLAN_CMD,
450 &scan_request,
451 sizeof(sl_si91x_req_bg_scan_t),
452 SL_SI91X_RETURN_IMMEDIATELY,
453 NULL,
454 NULL);
455 }
456
457 VERIFY_STATUS_AND_RETURN(status);
458 return status;
459 }
460
sl_wifi_get_stored_scan_results(sl_wifi_interface_t interface,sl_wifi_extended_scan_result_parameters_t * extended_scan_parameters)461 sl_status_t sl_wifi_get_stored_scan_results(sl_wifi_interface_t interface,
462 sl_wifi_extended_scan_result_parameters_t *extended_scan_parameters)
463 {
464 return sli_wifi_get_stored_scan_results(interface, extended_scan_parameters);
465 }
466
sl_wifi_connect(sl_wifi_interface_t interface,const sl_wifi_client_configuration_t * ap,uint32_t timeout_ms)467 sl_status_t sl_wifi_connect(sl_wifi_interface_t interface,
468 const sl_wifi_client_configuration_t *ap,
469 uint32_t timeout_ms)
470 {
471 sl_status_t status;
472 sl_si91x_req_psk_t psk_request;
473 sl_si91x_req_eap_config_t eap_req = { 0 };
474 sl_si91x_join_request_t join_request;
475 sl_wifi_buffer_t *buffer = NULL;
476 sl_si91x_packet_t *packet = NULL;
477 sl_si91x_req_scan_t scan_request = { 0 };
478 uint8_t uid_len = 0;
479 uint8_t psk_len = 0;
480 uint8_t key_len = 0;
481 sl_wifi_credential_t cred = { 0 };
482
483 if (!device_initialized) {
484 return SL_STATUS_NOT_INITIALIZED;
485 }
486
487 if (interface & SL_WIFI_AP_INTERFACE) {
488 return SL_STATUS_NOT_SUPPORTED;
489 }
490
491 if (!sl_wifi_is_interface_up(interface)) {
492 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
493 }
494
495 SL_WIFI_ARGS_CHECK_NULL_POINTER(ap);
496 memset(&scan_request, 0, sizeof(scan_request));
497 //! copying SSID & length
498 if (ap->ssid.length > 0) {
499 memcpy(scan_request.ssid, ap->ssid.value, ap->ssid.length);
500 } else {
501 return SL_STATUS_INVALID_PARAMETER;
502 }
503
504 // Configure channel bitmap for selective channel scan
505
506 if ((interface & SL_WIFI_CLIENT_2_4GHZ_INTERFACE) && (ap->channel_bitmap.channel_bitmap_2_4 > 0)) {
507 memcpy(&scan_request.channel_bit_map_2_4,
508 &ap->channel_bitmap.channel_bitmap_2_4,
509 sizeof(scan_request.channel_bit_map_2_4));
510 }
511
512 if ((interface & SL_WIFI_CLIENT_5GHZ_INTERFACE) && (ap->channel_bitmap.channel_bitmap_5 > 0)) {
513 memcpy(&scan_request.channel_bit_map_5,
514 &ap->channel_bitmap.channel_bitmap_5,
515 sizeof(scan_request.channel_bit_map_5));
516 }
517
518 sl_wifi_max_tx_power_t wifi_max_tx_power = get_max_tx_power();
519 // Within the 1-byte scan_feature_bimap variable, last 5 bits(bit 3 through bit 7) are allocated for
520 // encoding the transmit power during scan procedure.
521 scan_request.scan_feature_bitmap = (wifi_max_tx_power.scan_tx_power << 3);
522
523 if (advanced_scan_configuration.active_channel_time != SL_WIFI_DEFAULT_ACTIVE_CHANNEL_SCAN_TIME) {
524 sl_status_t status =
525 sl_si91x_configure_timeout(SL_SI91X_CHANNEL_ACTIVE_SCAN_TIMEOUT, advanced_scan_configuration.active_channel_time);
526 VERIFY_STATUS_AND_RETURN(status);
527 }
528 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_SCAN,
529 SI91X_WLAN_CMD,
530 &scan_request,
531 sizeof(scan_request),
532 SL_SI91X_WAIT_FOR(60000),
533 NULL,
534 NULL);
535
536 VERIFY_STATUS_AND_RETURN(status);
537
538 if ((SL_WIFI_WPA_ENTERPRISE == ap->security) || (SL_WIFI_WPA2_ENTERPRISE == ap->security)
539 || (SL_WIFI_WPA3_ENTERPRISE == ap->security) || (SL_WIFI_WPA3_TRANSITION_ENTERPRISE == ap->security)) {
540 memset(&eap_req, 0, sizeof(eap_req));
541 eap_req.user_identity[0] = '"';
542 eap_req.password[0] = '"';
543
544 status = sl_si91x_host_get_credentials(ap->credential_id, SL_WIFI_EAP_CREDENTIAL, &cred);
545 VERIFY_STATUS_AND_RETURN(status);
546
547 memcpy(&(eap_req.user_identity[1]), cred.eap.username, 63);
548 memcpy(&(eap_req.password[1]), cred.eap.password, 127);
549 uid_len = strlen((char *)eap_req.user_identity);
550 psk_len = strlen((char *)eap_req.password);
551 eap_req.user_identity[uid_len] = '"';
552 eap_req.password[psk_len] = '"';
553 eap_req.user_identity[uid_len + 1] = 0;
554 eap_req.password[psk_len + 1] = 0;
555
556 // copy enterprise configuration data
557 if (SL_WIFI_EAP_TLS_ENCRYPTION == ap->encryption) {
558 strcpy((char *)eap_req.eap_method, SL_EAP_TLS_METHOD);
559 } else if (SL_WIFI_EAP_TTLS_ENCRYPTION == ap->encryption) {
560 strcpy((char *)eap_req.eap_method, SL_EAP_TTLS_METHOD);
561 } else if (SL_WIFI_EAP_FAST_ENCRYPTION == ap->encryption) {
562 strcpy((char *)eap_req.eap_method, SL_EAP_FAST_METHOD);
563 } else if (SL_WIFI_PEAP_MSCHAPV2_ENCRYPTION == ap->encryption) {
564 strcpy((char *)eap_req.eap_method, SL_EAP_PEAP_METHOD);
565 } else if (SL_WIFI_EAP_LEAP_ENCRYPTION == ap->encryption) {
566 strcpy((char *)eap_req.eap_method, SL_EAP_LEAP_METHOD);
567 } else {
568 return SL_STATUS_WIFI_INVALID_ENCRYPTION_METHOD;
569 }
570
571 strcpy((char *)eap_req.inner_method, SL_EAP_INNER_METHOD);
572 memcpy(eap_req.okc_enable, &cred.eap.eap_flags, sizeof(cred.eap.eap_flags));
573
574 key_len = strlen((const char *)cred.eap.certificate_key);
575 if ((key_len > 0)) {
576 eap_req.private_key_password[0] = '"';
577 strcpy((char *)eap_req.private_key_password, (const char *)cred.eap.certificate_key);
578 eap_req.private_key_password[key_len + 1] = '"';
579 } else {
580 strcpy((char *)eap_req.private_key_password, SL_DEFAULT_PRIVATE_KEY_PASSWORD);
581 }
582
583 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_EAP_CONFIG,
584 SI91X_WLAN_CMD,
585 &eap_req,
586 sizeof(eap_req),
587 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
588 NULL,
589 NULL);
590 VERIFY_STATUS_AND_RETURN(status);
591 } else if ((SL_WIFI_WPA == ap->security) || (SL_WIFI_WPA2 == ap->security) || (SL_WIFI_WPA_WPA2_MIXED == ap->security)
592 || (SL_WIFI_WPA3 == ap->security) || (SL_WIFI_WPA3_TRANSITION == ap->security)) {
593
594 memset(&psk_request, 0, sizeof(psk_request));
595 status = sl_si91x_host_get_credentials(ap->credential_id, SL_WIFI_PSK_CREDENTIAL, &cred);
596 VERIFY_STATUS_AND_RETURN(status);
597 psk_request.type = cred.type == SL_WIFI_PSK_CREDENTIAL ? 1 : 2;
598 memcpy(psk_request.psk_or_pmk, cred.pmk.value, SL_WIFI_MAX_PMK_LENGTH);
599
600 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_HOST_PSK,
601 SI91X_WLAN_CMD,
602 &psk_request,
603 sizeof(psk_request),
604 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
605 NULL,
606 NULL);
607 VERIFY_STATUS_AND_RETURN(status);
608 } else if (SL_WIFI_WEP == ap->security) {
609 return SL_STATUS_NOT_SUPPORTED;
610 } else if (SL_WIFI_OPEN != ap->security) {
611 return SL_STATUS_WIFI_UNKNOWN_SECURITY_TYPE;
612 }
613
614 memset(&join_request, 0, sizeof(join_request));
615
616 status = get_configured_join_request(SL_WIFI_CLIENT_INTERFACE, ap, &join_request);
617
618 VERIFY_STATUS_AND_RETURN(status);
619
620 status =
621 sl_si91x_driver_send_command(RSI_WLAN_REQ_JOIN,
622 SI91X_WLAN_CMD,
623 &join_request,
624 sizeof(join_request),
625 timeout_ms ? SL_SI91X_WAIT_FOR_RESPONSE(timeout_ms) : SL_SI91X_RETURN_IMMEDIATELY,
626 NULL,
627 &buffer);
628
629 if (timeout_ms != 0 && status != SL_STATUS_OK) {
630 if (buffer != NULL) {
631 sl_si91x_host_free_buffer(buffer);
632 }
633 sl_status_t temp_status = sl_si91x_driver_send_command(RSI_WLAN_REQ_INIT,
634 SI91X_WLAN_CMD,
635 NULL,
636 0,
637 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
638 NULL,
639 NULL);
640 VERIFY_STATUS_AND_RETURN(temp_status);
641 }
642
643 VERIFY_STATUS_AND_RETURN(status);
644
645 packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
646
647 if (packet->data[0] != 'C') {
648 sl_si91x_host_free_buffer(buffer);
649 return SL_STATUS_NOT_AVAILABLE;
650 }
651
652 sl_si91x_host_free_buffer(buffer);
653 return SL_STATUS_OK;
654 }
655
sl_wifi_set_advanced_client_configuration(sl_wifi_interface_t interface,const sl_wifi_advanced_client_configuration_t * configuration)656 sl_status_t sl_wifi_set_advanced_client_configuration(sl_wifi_interface_t interface,
657 const sl_wifi_advanced_client_configuration_t *configuration)
658 {
659 if (!device_initialized) {
660 return SL_STATUS_NOT_INITIALIZED;
661 }
662
663 if (interface & SL_WIFI_AP_INTERFACE) {
664 return SL_STATUS_NOT_SUPPORTED;
665 }
666
667 sl_si91x_rejoin_params_t rejoin_request = { .max_retry_attempts = configuration->max_retry_attempts,
668 .scan_interval = configuration->scan_interval,
669 .beacon_missed_count = configuration->beacon_missed_count,
670 .first_time_retry_enable = configuration->first_time_retry_enable };
671
672 if (rejoin_request.beacon_missed_count < 40) {
673 SL_DEBUG_LOG("\r\nBeacon Missed Count minimum value should be 40, Updating to the minimum value.\r\n");
674 rejoin_request.beacon_missed_count = 40;
675 }
676
677 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_REJOIN_PARAMS,
678 SI91X_WLAN_CMD,
679 &rejoin_request,
680 sizeof(rejoin_request),
681 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
682 NULL,
683 NULL);
684 VERIFY_STATUS_AND_RETURN(status);
685
686 memcpy(&advanced_client_configuration, configuration, sizeof(sl_wifi_advanced_client_configuration_t));
687
688 return status;
689 }
690
sl_wifi_get_signal_strength(sl_wifi_interface_t interface,int32_t * rssi)691 sl_status_t sl_wifi_get_signal_strength(sl_wifi_interface_t interface, int32_t *rssi)
692 {
693 sl_status_t status;
694 sl_wifi_buffer_t *buffer = NULL;
695
696 if (!device_initialized) {
697 return SL_STATUS_NOT_INITIALIZED;
698 }
699
700 SL_VERIFY_POINTER_OR_RETURN(rssi, SL_STATUS_WIFI_NULL_PTR_ARG);
701
702 if (interface & SL_WIFI_AP_INTERFACE) {
703 return SL_STATUS_NOT_SUPPORTED;
704 }
705
706 if (!sl_wifi_is_interface_up(interface)) {
707 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
708 }
709
710 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_RSSI,
711 SI91X_WLAN_CMD,
712 NULL,
713 0,
714 SL_SI91X_WAIT_FOR_RESPONSE(15000),
715 NULL,
716 &buffer);
717 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
718 sl_si91x_host_free_buffer(buffer);
719 }
720 VERIFY_STATUS_AND_RETURN(status);
721
722 sl_si91x_packet_t *packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
723 *rssi = -(packet->data[0]);
724 sl_si91x_host_free_buffer(buffer);
725 return SL_STATUS_OK;
726 }
727
sl_wifi_get_sta_tsf(sl_wifi_interface_t interface,sl_wifi_tsf64_t * tsf)728 sl_status_t sl_wifi_get_sta_tsf(sl_wifi_interface_t interface, sl_wifi_tsf64_t *tsf)
729 {
730 sl_status_t status;
731 sl_wifi_buffer_t *buffer = NULL;
732
733 if (!device_initialized) {
734 return SL_STATUS_NOT_INITIALIZED;
735 }
736
737 SL_VERIFY_POINTER_OR_RETURN(tsf, SL_STATUS_WIFI_NULL_PTR_ARG);
738
739 if (interface & SL_WIFI_AP_INTERFACE) {
740 return SL_STATUS_NOT_SUPPORTED;
741 }
742
743 if (!sl_wifi_is_interface_up(interface)) {
744 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
745 }
746
747 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_TSF,
748 SI91X_WLAN_CMD,
749 NULL,
750 0,
751 SL_SI91X_WAIT_FOR_RESPONSE(15000),
752 NULL,
753 &buffer);
754 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
755 sl_si91x_host_free_buffer(buffer);
756 }
757 VERIFY_STATUS_AND_RETURN(status);
758
759 sl_si91x_packet_t *packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
760 memcpy(tsf, packet->data, packet->length);
761 sl_si91x_host_free_buffer(buffer);
762 return SL_STATUS_OK;
763 }
764
sl_wifi_set_mac_address(sl_wifi_interface_t interface,const sl_mac_address_t * mac_address)765 sl_status_t sl_wifi_set_mac_address(sl_wifi_interface_t interface, const sl_mac_address_t *mac_address)
766 {
767 UNUSED_PARAMETER(interface);
768
769 SL_VERIFY_POINTER_OR_RETURN(mac_address, SL_STATUS_NULL_POINTER);
770
771 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_SET_MAC_ADDRESS,
772 SI91X_WLAN_CMD,
773 mac_address,
774 sizeof(sl_mac_address_t),
775 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
776 NULL,
777 NULL);
778 VERIFY_STATUS_AND_RETURN(status);
779 return SL_STATUS_OK;
780 }
781
sl_wifi_get_mac_address(sl_wifi_interface_t interface,sl_mac_address_t * mac)782 sl_status_t sl_wifi_get_mac_address(sl_wifi_interface_t interface, sl_mac_address_t *mac)
783 {
784 sl_status_t status;
785 sl_wifi_buffer_t *buffer = NULL;
786
787 SL_WIFI_ARGS_CHECK_NULL_POINTER(mac);
788
789 if (!device_initialized) {
790 return SL_STATUS_NOT_INITIALIZED;
791 }
792
793 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_MAC_ADDRESS,
794 SI91X_WLAN_CMD,
795 NULL,
796 0,
797 SL_SI91X_WAIT_FOR_RESPONSE(15000),
798 NULL,
799 &buffer);
800 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
801 sl_si91x_host_free_buffer(buffer);
802 }
803 VERIFY_STATUS_AND_RETURN(status);
804
805 sl_si91x_packet_t *packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
806 if (packet->length > 0) {
807 // In Concurrent mode, for Client Interface, mac address will be at offset 0
808 uint8_t mac_address_offset = 0;
809 if ((SL_SI91X_CONCURRENT_MODE == get_opermode()) && (SL_WIFI_AP_INTERFACE == interface)) {
810 // In Concurrent mode, for AP Interface, mac address will be at offset 6
811 mac_address_offset = sizeof(sl_mac_address_t);
812 }
813 memcpy(mac->octet, packet->data + mac_address_offset, sizeof(*mac));
814 }
815 sl_si91x_host_free_buffer(buffer);
816 return SL_STATUS_OK;
817 }
818
sl_wifi_set_channel(sl_wifi_interface_t interface,sl_wifi_channel_t channel)819 sl_status_t sl_wifi_set_channel(sl_wifi_interface_t interface, sl_wifi_channel_t channel)
820 {
821 UNUSED_PARAMETER(channel);
822 if (!device_initialized) {
823 return SL_STATUS_NOT_INITIALIZED;
824 }
825
826 if (!sl_wifi_is_interface_up(interface)) {
827 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
828 }
829
830 // Firmware doesn't support to change the channel of a running Access Point interface.
831 return SL_STATUS_NOT_SUPPORTED;
832 }
833
sl_wifi_get_channel(sl_wifi_interface_t interface,sl_wifi_channel_t * channel_info)834 sl_status_t sl_wifi_get_channel(sl_wifi_interface_t interface, sl_wifi_channel_t *channel_info)
835 {
836 sl_status_t status = SL_STATUS_FAIL;
837 sl_wifi_buffer_t *buffer = NULL;
838 rsi_wlan_cmd_request_t command = 0;
839
840 if (!device_initialized) {
841 return SL_STATUS_NOT_INITIALIZED;
842 }
843 if (!sl_wifi_is_interface_up(interface)) {
844 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
845 }
846
847 if ((interface == SL_WIFI_CLIENT_2_4GHZ_INTERFACE) || (interface == SL_WIFI_CLIENT_5GHZ_INTERFACE))
848 command = RSI_WLAN_REQ_QUERY_NETWORK_PARAMS;
849 else if ((interface == SL_WIFI_AP_2_4GHZ_INTERFACE) || (interface == SL_WIFI_AP_5GHZ_INTERFACE))
850 command = RSI_WLAN_REQ_QUERY_GO_PARAMS;
851
852 status = sl_si91x_driver_send_command(command,
853 SI91X_WLAN_CMD,
854 NULL,
855 0,
856 SL_SI91X_WAIT_FOR_RESPONSE(SL_SI91X_GET_CHANNEL_TIMEOUT),
857 NULL,
858 &buffer);
859 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
860 sl_si91x_host_free_buffer(buffer);
861 }
862 VERIFY_STATUS_AND_RETURN(status);
863
864 sl_si91x_packet_t *packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
865
866 switch (interface) {
867 case SL_WIFI_CLIENT_2_4GHZ_INTERFACE: {
868 channel_info->channel = ((sl_si91x_network_params_response_t *)packet->data)->channel_number;
869 channel_info->band = SL_WIFI_BAND_2_4GHZ;
870 break;
871 }
872 case SL_WIFI_AP_2_4GHZ_INTERFACE: {
873 memcpy(&channel_info->channel, ((sl_si91x_client_info_response *)packet->data)->channel_number, 2);
874 channel_info->band = SL_WIFI_BAND_2_4GHZ;
875 break;
876 }
877 default:
878 break;
879 }
880
881 sl_si91x_host_free_buffer(buffer);
882 return status;
883 }
884
885 /*
886 * This API doesn't have any affect if it is called after connect/start ap.
887 */
sl_wifi_set_max_tx_power(sl_wifi_interface_t interface,sl_wifi_max_tx_power_t max_tx_power)888 sl_status_t sl_wifi_set_max_tx_power(sl_wifi_interface_t interface, sl_wifi_max_tx_power_t max_tx_power)
889 {
890 if (!device_initialized) {
891 return SL_STATUS_NOT_INITIALIZED;
892 }
893
894 if (
895 (interface & SL_WIFI_CLIENT_INTERFACE) // For the client interface, it’s necessary to check if the interface is up. However, for the AP interface, this check isn’t required since this API will be called before starting the AP.
896 && (!sl_wifi_is_interface_up(interface))) {
897 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
898 }
899
900 uint8_t max_scan_tx_power = max_tx_power.scan_tx_power;
901 uint8_t max_join_tx_power = max_tx_power.join_tx_power;
902
903 if ((max_scan_tx_power < 1 || max_scan_tx_power > 31) || (max_join_tx_power < 1 || max_join_tx_power > 31)) {
904 return SL_STATUS_INVALID_PARAMETER;
905 }
906
907 save_max_tx_power(max_scan_tx_power, max_join_tx_power);
908 return SL_STATUS_OK;
909 }
910
sl_wifi_get_max_tx_power(sl_wifi_interface_t interface,sl_wifi_max_tx_power_t * max_tx_power)911 sl_status_t sl_wifi_get_max_tx_power(sl_wifi_interface_t interface, sl_wifi_max_tx_power_t *max_tx_power)
912 {
913 if (!device_initialized) {
914 return SL_STATUS_NOT_INITIALIZED;
915 }
916
917 if (!sl_wifi_is_interface_up(interface)) {
918 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
919 }
920
921 SL_WIFI_ARGS_CHECK_NULL_POINTER(max_tx_power);
922
923 *max_tx_power = get_max_tx_power();
924
925 return SL_STATUS_OK;
926 }
927
sl_wifi_start_ap(sl_wifi_interface_t interface,const sl_wifi_ap_configuration_t * configuration)928 sl_status_t sl_wifi_start_ap(sl_wifi_interface_t interface, const sl_wifi_ap_configuration_t *configuration)
929 {
930 sl_status_t status = SL_STATUS_OK;
931 sl_wifi_buffer_t *rx_buffer = NULL;
932 sl_si91x_packet_t *join_response = NULL;
933 sl_si91x_ap_config_request request = { 0 };
934 sl_si91x_join_request_t join_request = { 0 };
935 sl_wifi_credential_t cred = { 0 };
936
937 if (!device_initialized) {
938 return SL_STATUS_NOT_INITIALIZED;
939 }
940
941 memcpy(request.ssid, configuration->ssid.value, configuration->ssid.length);
942 request.security_type = configuration->security;
943
944 //This encryption convertions is only required in access point mode
945 status = convert_sl_wifi_to_sl_si91x_encryption(configuration->encryption, &request.encryption_mode);
946 VERIFY_STATUS_AND_RETURN(status);
947
948 //Configures TDI[7-4] value here
949 if ((configuration->security == SL_WIFI_WPA3) || (configuration->security == SL_WIFI_WPA3_TRANSITION)) {
950 request.encryption_mode |= configuration->tdi_flags & 0xF0;
951 }
952 status = sl_si91x_host_get_credentials(configuration->credential_id, SL_WIFI_PSK_CREDENTIAL, &cred);
953 VERIFY_STATUS_AND_RETURN(status);
954
955 memcpy(request.psk, cred.psk.value, sizeof(request.psk));
956
957 request.channel = configuration->channel.channel;
958 request.beacon_interval = configuration->beacon_interval;
959 request.dtim_period = configuration->dtim_beacon_count;
960 request.max_sta_support = configuration->maximum_clients;
961 if (configuration->keepalive_type) {
962 request.ap_keepalive_type = configuration->keepalive_type;
963 request.ap_keepalive_period = configuration->client_idle_timeout;
964 }
965 if (configuration->beacon_stop) {
966 // Using a free bit in ap_keepalive_type since there are no available bits in join feature bitmap.
967 request.ap_keepalive_type |= BIT(2);
968 }
969
970 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_AP_CONFIGURATION,
971 SI91X_WLAN_CMD,
972 &request,
973 sizeof(request),
974 SL_SI91X_WAIT_FOR(15000),
975 NULL,
976 NULL);
977 VERIFY_STATUS_AND_RETURN(status);
978
979 if (configuration->is_11n_enabled) {
980 sl_si91x_request_ap_high_throughput_capability_t htcaps = { 0 };
981 htcaps.mode_11n_enable = true;
982 htcaps.ht_caps_bitmap = SL_WIFI_HT_CAPS_NUM_RX_STBC | SL_WIFI_HT_CAPS_SHORT_GI_20MHZ | SL_WIFI_HT_CAPS_GREENFIELD_EN
983 | SL_WIFI_HT_CAPS_SUPPORT_CH_WIDTH;
984 status = sli_si91x_set_high_throughput_capability(SL_WIFI_AP_INTERFACE, htcaps);
985 VERIFY_STATUS_AND_RETURN(status);
986 }
987
988 status = get_configured_join_request(SL_WIFI_AP_INTERFACE, configuration, &join_request);
989 VERIFY_STATUS_AND_RETURN(status);
990
991 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_JOIN,
992 SI91X_WLAN_CMD,
993 &join_request,
994 sizeof(join_request),
995 SL_SI91X_WAIT_FOR_RESPONSE(15000),
996 NULL,
997 &rx_buffer);
998 if ((status != SL_STATUS_OK) && (rx_buffer != NULL)) {
999 sl_si91x_host_free_buffer(rx_buffer);
1000 }
1001 VERIFY_STATUS_AND_RETURN(status);
1002
1003 join_response = sl_si91x_host_get_buffer_data(rx_buffer, 0, NULL);
1004
1005 if (join_response->data[0] != 'G') {
1006 sl_si91x_host_free_buffer(rx_buffer);
1007 return SL_STATUS_NOT_AVAILABLE;
1008 }
1009
1010 save_ap_configuration(configuration);
1011 if (interface == SL_WIFI_AP_2_4GHZ_INTERFACE || interface == SL_WIFI_AP_INTERFACE)
1012 interface_is_up[SL_WIFI_AP_2_4GHZ_INTERFACE_INDEX] = true;
1013 else if (interface == SL_WIFI_AP_5GHZ_INTERFACE)
1014 interface_is_up[SL_WIFI_AP_5GHZ_INTERFACE_INDEX] = true;
1015
1016 sl_si91x_host_free_buffer(rx_buffer);
1017 return SL_STATUS_OK;
1018 }
1019
sl_wifi_get_pairwise_master_key(sl_wifi_interface_t interface,const uint8_t type,const sl_wifi_ssid_t * ssid,const char * pre_shared_key,uint8_t * pairwise_master_key)1020 sl_status_t sl_wifi_get_pairwise_master_key(sl_wifi_interface_t interface,
1021 const uint8_t type,
1022 const sl_wifi_ssid_t *ssid,
1023 const char *pre_shared_key,
1024 uint8_t *pairwise_master_key)
1025 {
1026 UNUSED_PARAMETER(interface);
1027 sl_status_t status;
1028 sl_wifi_buffer_t *buffer = NULL;
1029 sl_si91x_req_psk_t pairwise_master_key_request = { 0 };
1030
1031 if (pairwise_master_key == NULL) {
1032 return SL_STATUS_WIFI_NULL_PTR_ARG;
1033 }
1034
1035 pairwise_master_key_request.type = type;
1036 memcpy(pairwise_master_key_request.psk_or_pmk, pre_shared_key, strlen(pre_shared_key));
1037 memcpy(pairwise_master_key_request.ap_ssid, ssid->value, ssid->length);
1038
1039 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_HOST_PSK,
1040 SI91X_WLAN_CMD,
1041 &pairwise_master_key_request,
1042 sizeof(sl_si91x_req_psk_t),
1043 SL_SI91X_WAIT_FOR_RESPONSE(35000),
1044 NULL,
1045 &buffer);
1046 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
1047 sl_si91x_host_free_buffer(buffer);
1048 }
1049 VERIFY_STATUS_AND_RETURN(status);
1050
1051 sl_si91x_packet_t *packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
1052 memcpy(pairwise_master_key, packet->data, packet->length);
1053 sl_si91x_host_free_buffer(buffer);
1054 return SL_STATUS_OK;
1055 }
1056
sl_wifi_get_associated_client_list(void * client_list_buffer,uint16_t buffer_length,uint32_t timeout)1057 sl_status_t sl_wifi_get_associated_client_list(void *client_list_buffer, uint16_t buffer_length, uint32_t timeout)
1058 {
1059 UNUSED_PARAMETER(client_list_buffer);
1060 UNUSED_PARAMETER(buffer_length);
1061 UNUSED_PARAMETER(timeout);
1062 return SL_STATUS_NOT_SUPPORTED;
1063 // sl_status_t status;
1064 // sl_wifi_buffer_t *buffer;
1065
1066 // status = sl_si91x_driver_send_command(RSI_WLAN_REQ_QUERY_GO_PARAMS,
1067 // SI91X_WLAN_CMD,
1068 // NULL,
1069 // 0,
1070 // SL_SI91X_WAIT_FOR_RESPONSE(10000),
1071 // NULL,
1072 // &buffer);
1073 // if (status == SL_STATUS_OK) {
1074 // sl_si91x_packet_t *packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
1075 // // si91x_go_parameters_t* data = &packet->data;
1076 // // Process data here
1077
1078 // sl_si91x_host_free_buffer(buffer);
1079 // }
1080 // return status;
1081 }
1082
sl_wifi_disconnect_ap_client(sl_wifi_interface_t interface,const sl_mac_address_t * mac,sl_wifi_deauth_reason_t reason)1083 sl_status_t sl_wifi_disconnect_ap_client(sl_wifi_interface_t interface,
1084 const sl_mac_address_t *mac,
1085 sl_wifi_deauth_reason_t reason)
1086 {
1087 UNUSED_PARAMETER(reason);
1088 SL_WIFI_ARGS_CHECK_NULL_POINTER(mac);
1089
1090 if (!device_initialized) {
1091 return SL_STATUS_NOT_INITIALIZED;
1092 }
1093
1094 if (!sl_wifi_is_interface_up(interface)) {
1095 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1096 }
1097
1098 sl_si91x_disassociation_request_t disconnect_request = { 0 };
1099
1100 disconnect_request.mode_flag = SL_SI91X_WIFI_AP_VAP_ID;
1101 memcpy(&disconnect_request.client_mac_address, mac, sizeof(sl_mac_address_t));
1102
1103 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_DISCONNECT,
1104 SI91X_WLAN_CMD,
1105 &disconnect_request,
1106 sizeof(disconnect_request),
1107 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
1108 (void *)mac,
1109 NULL);
1110
1111 VERIFY_STATUS_AND_RETURN(status);
1112 return status;
1113 }
1114
sl_wifi_get_ap_client_info(sl_wifi_interface_t interface,sl_wifi_client_info_response_t * client_info)1115 sl_status_t sl_wifi_get_ap_client_info(sl_wifi_interface_t interface, sl_wifi_client_info_response_t *client_info)
1116 {
1117 sl_status_t status;
1118 sl_wifi_buffer_t *buffer = NULL;
1119 sl_si91x_packet_t *packet;
1120 sl_si91x_client_info_response sl_si91x_client_info_response = { 0 };
1121
1122 if (!device_initialized) {
1123 return SL_STATUS_NOT_INITIALIZED;
1124 }
1125
1126 if (interface & SL_WIFI_CLIENT_INTERFACE) {
1127 return SL_STATUS_NOT_SUPPORTED;
1128 }
1129
1130 if (!sl_wifi_is_interface_up(SL_WIFI_AP_INTERFACE)) {
1131 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1132 }
1133
1134 SL_WIFI_ARGS_CHECK_NULL_POINTER(client_info);
1135
1136 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_QUERY_GO_PARAMS,
1137 SI91X_WLAN_CMD,
1138 NULL,
1139 0,
1140 SL_SI91X_WAIT_FOR_COMMAND_RESPONSE,
1141 NULL,
1142 &buffer);
1143 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
1144 sl_si91x_host_free_buffer(buffer);
1145 }
1146 VERIFY_STATUS_AND_RETURN(status);
1147
1148 packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
1149
1150 memcpy(&sl_si91x_client_info_response, packet->data, sizeof(sl_si91x_client_info_response));
1151 convert_si91x_wifi_client_info(client_info, &sl_si91x_client_info_response);
1152
1153 sl_si91x_host_free_buffer(buffer);
1154 return status;
1155 }
1156
sl_wifi_get_firmware_version(sl_wifi_firmware_version_t * version)1157 sl_status_t sl_wifi_get_firmware_version(sl_wifi_firmware_version_t *version)
1158 {
1159 return sl_si91x_get_firmware_version((sl_si91x_firmware_version_t *)version);
1160 }
1161
sl_wifi_get_wireless_info(sl_si91x_rsp_wireless_info_t * info)1162 sl_status_t sl_wifi_get_wireless_info(sl_si91x_rsp_wireless_info_t *info)
1163 {
1164 sl_status_t status = 0;
1165 sl_wifi_buffer_t *buffer = NULL;
1166
1167 if (!device_initialized) {
1168 return SL_STATUS_NOT_INITIALIZED;
1169 }
1170 SL_WIFI_ARGS_CHECK_NULL_POINTER(info);
1171
1172 if (get_opermode() == SL_SI91X_ACCESS_POINT_MODE) {
1173 // Send cmd for wlan info in AP mode
1174 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_QUERY_GO_PARAMS,
1175 SI91X_WLAN_CMD,
1176 NULL,
1177 0,
1178 SL_SI91X_WAIT_FOR_RESPONSE(1000),
1179 NULL,
1180 &buffer);
1181 } else if ((get_opermode() == SL_SI91X_CLIENT_MODE) || (get_opermode() == SL_SI91X_ENTERPRISE_CLIENT_MODE)) {
1182 //! Send cmd for wlan info in client mode
1183 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_QUERY_NETWORK_PARAMS,
1184 SI91X_WLAN_CMD,
1185 NULL,
1186 0,
1187 SL_SI91X_WAIT_FOR_RESPONSE(1000),
1188 NULL,
1189 &buffer);
1190 } else {
1191 return SL_STATUS_NOT_SUPPORTED;
1192 }
1193
1194 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
1195 sl_si91x_host_free_buffer(buffer);
1196 }
1197 VERIFY_STATUS_AND_RETURN(status);
1198
1199 sl_si91x_packet_t *packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
1200
1201 memset((sl_si91x_rsp_wireless_info_t *)info, 0, sizeof(sl_si91x_rsp_wireless_info_t));
1202
1203 //In AP mode, receives a buffer equivalent to sl_si91x_client_info_response.
1204 if (packet->length > 0 && get_opermode() == SL_SI91X_ACCESS_POINT_MODE) {
1205 sl_si91x_client_info_response *response = (sl_si91x_client_info_response *)packet->data;
1206 // wlan state: no of stations connected in AP mode
1207 memcpy(&info->wlan_state, (uint16_t *)&response->sta_count, sizeof(uint16_t));
1208 memcpy(&info->channel_number, (uint16_t *)&response->channel_number, sizeof(uint16_t));
1209 memcpy(info->ssid, response->ssid, MIN(sizeof(info->ssid), sizeof(response->ssid)));
1210 memcpy(info->mac_address, response->mac_address, 6);
1211 // PSK for AP mode, PMK for Client mode
1212 memcpy(info->psk_pmk, response->psk, 64);
1213 memcpy(info->ipv4_address, response->ipv4_address, 4);
1214 memcpy(info->ipv6_address, response->ipv6_address, 16);
1215 }
1216 //In Client mode, receives a buffer equivalent to sl_si91x_network_params_response_t.
1217 else if (packet->length > 0
1218 && ((get_opermode() == SL_SI91X_CLIENT_MODE) || (get_opermode() == SL_SI91X_ENTERPRISE_CLIENT_MODE))) {
1219 sl_si91x_network_params_response_t *response = (sl_si91x_network_params_response_t *)packet->data;
1220 memcpy(&info->wlan_state, (uint16_t *)&response->wlan_state, sizeof(uint8_t));
1221 memcpy((uint8_t *)&info->channel_number, &response->channel_number, sizeof(uint8_t));
1222 memcpy(info->ssid, response->ssid, MIN(sizeof(info->ssid), sizeof(response->ssid)));
1223 memcpy(info->mac_address, response->mac_address, 6);
1224 memcpy(&info->sec_type, &response->sec_type, sizeof(uint8_t));
1225 // PSK for AP mode, PMK for Client mode
1226 memcpy(info->psk_pmk, response->psk, 64);
1227 memcpy(info->ipv4_address, response->ipv4_address, 4);
1228 memcpy(info->ipv6_address, response->ipv6_address, 16);
1229 }
1230
1231 sl_si91x_host_free_buffer(buffer);
1232 return status;
1233 }
1234
sl_wifi_get_firmware_size(void * buffer,uint32_t * fw_image_size)1235 sl_status_t sl_wifi_get_firmware_size(void *buffer, uint32_t *fw_image_size)
1236 {
1237 return sl_si91x_get_firmware_size(buffer, fw_image_size);
1238 }
1239
sl_wifi_disconnect(sl_wifi_interface_t interface)1240 sl_status_t sl_wifi_disconnect(sl_wifi_interface_t interface)
1241 {
1242 if (!device_initialized) {
1243 return SL_STATUS_NOT_INITIALIZED;
1244 }
1245
1246 if (interface & SL_WIFI_AP_INTERFACE) {
1247 return SL_STATUS_NOT_SUPPORTED;
1248 }
1249
1250 if (!sl_wifi_is_interface_up(interface)) {
1251 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1252 }
1253
1254 sl_si91x_disassociation_request_t disconnect_request = { 0 };
1255
1256 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_DISCONNECT,
1257 SI91X_WLAN_CMD,
1258 &disconnect_request,
1259 sizeof(disconnect_request),
1260 SL_NCP_DEFAULT_COMMAND_WAIT_TIME,
1261 NULL,
1262 NULL);
1263 VERIFY_STATUS_AND_RETURN(status);
1264
1265 reset_coex_current_performance_profile();
1266
1267 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_INIT,
1268 SI91X_WLAN_CMD,
1269 NULL,
1270 0,
1271 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
1272 NULL,
1273 NULL);
1274 VERIFY_STATUS_AND_RETURN(status);
1275
1276 return status;
1277 }
1278
sl_wifi_stop_ap(sl_wifi_interface_t interface)1279 sl_status_t sl_wifi_stop_ap(sl_wifi_interface_t interface)
1280 {
1281 sl_status_t status = SL_STATUS_OK;
1282 sl_si91x_disassociation_request_t disconnect_request = { 0 };
1283
1284 if (!device_initialized) {
1285 return SL_STATUS_NOT_INITIALIZED;
1286 }
1287
1288 if (interface & SL_WIFI_CLIENT_INTERFACE) {
1289 return SL_STATUS_NOT_SUPPORTED;
1290 }
1291
1292 if (!sl_wifi_is_interface_up(interface)) {
1293 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1294 }
1295
1296 disconnect_request.mode_flag = SL_SI91X_WIFI_AP_VAP_ID;
1297 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_AP_STOP,
1298 SI91X_WLAN_CMD,
1299 &disconnect_request,
1300 sizeof(disconnect_request),
1301 SL_NCP_DEFAULT_COMMAND_WAIT_TIME,
1302 NULL,
1303 NULL);
1304 VERIFY_STATUS_AND_RETURN(status);
1305
1306 reset_ap_configuration();
1307 if (interface == SL_WIFI_AP_2_4GHZ_INTERFACE || interface == SL_WIFI_AP_INTERFACE)
1308 interface_is_up[SL_WIFI_AP_2_4GHZ_INTERFACE_INDEX] = false;
1309 else if (interface == SL_WIFI_AP_5GHZ_INTERFACE)
1310 interface_is_up[SL_WIFI_AP_5GHZ_INTERFACE_INDEX] = false;
1311
1312 return status;
1313 }
1314
sl_wifi_get_statistics(sl_wifi_interface_t interface,sl_wifi_statistics_t * statistics)1315 sl_status_t sl_wifi_get_statistics(sl_wifi_interface_t interface, sl_wifi_statistics_t *statistics)
1316 {
1317 sl_status_t status = SL_STATUS_OK;
1318 sl_wifi_buffer_t *buffer = NULL;
1319 sl_si91x_packet_t *packet;
1320
1321 if (!device_initialized) {
1322 return SL_STATUS_NOT_INITIALIZED;
1323 }
1324
1325 if (!sl_wifi_is_interface_up(interface)) {
1326 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1327 }
1328
1329 SL_WIFI_ARGS_CHECK_INVALID_INTERFACE(interface);
1330 SL_WIFI_ARGS_CHECK_NULL_POINTER(statistics);
1331
1332 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_EXT_STATS,
1333 SI91X_WLAN_CMD,
1334 NULL,
1335 0,
1336 SL_SI91X_WAIT_FOR_RESPONSE(30500),
1337 NULL,
1338 &buffer);
1339 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
1340 sl_si91x_host_free_buffer(buffer);
1341 }
1342 VERIFY_STATUS_AND_RETURN(status);
1343
1344 packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
1345 if (packet->length != sizeof(sl_wifi_statistics_t)) {
1346 sl_si91x_host_free_buffer(buffer);
1347 return SL_STATUS_FAIL;
1348 }
1349
1350 if (packet->length > 0) {
1351 memcpy(statistics, packet->data, packet->length);
1352 }
1353
1354 sl_si91x_host_free_buffer(buffer);
1355 return status;
1356 }
1357
sl_wifi_get_operational_statistics(sl_wifi_interface_t interface,sl_wifi_operational_statistics_t * operational_statistics)1358 sl_status_t sl_wifi_get_operational_statistics(sl_wifi_interface_t interface,
1359 sl_wifi_operational_statistics_t *operational_statistics)
1360 {
1361 sl_status_t status = SL_STATUS_OK;
1362 sl_wifi_buffer_t *buffer = NULL;
1363 sl_si91x_packet_t *packet;
1364
1365 if (!device_initialized) {
1366 return SL_STATUS_NOT_INITIALIZED;
1367 }
1368
1369 if (!sl_wifi_is_interface_up(interface)) {
1370 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1371 }
1372
1373 SL_WIFI_ARGS_CHECK_INVALID_INTERFACE(interface);
1374 SL_WIFI_ARGS_CHECK_NULL_POINTER(operational_statistics);
1375
1376 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_GET_STATS,
1377 SI91X_WLAN_CMD,
1378 NULL,
1379 0,
1380 SL_SI91X_WAIT_FOR_RESPONSE(30500),
1381 NULL,
1382 &buffer);
1383 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
1384 sl_si91x_host_free_buffer(buffer);
1385 }
1386 VERIFY_STATUS_AND_RETURN(status);
1387
1388 packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
1389 if (packet->length != sizeof(sl_wifi_operational_statistics_t)) {
1390 sl_si91x_host_free_buffer(buffer);
1391 return SL_STATUS_FAIL;
1392 }
1393
1394 if (packet->length > 0) {
1395 memcpy(operational_statistics, packet->data, packet->length);
1396 }
1397
1398 sl_si91x_host_free_buffer(buffer);
1399 return status;
1400 }
1401
sl_wifi_start_statistic_report(sl_wifi_interface_t interface,sl_wifi_channel_t channel)1402 sl_status_t sl_wifi_start_statistic_report(sl_wifi_interface_t interface, sl_wifi_channel_t channel)
1403 {
1404 if (!device_initialized) {
1405 return SL_STATUS_NOT_INITIALIZED;
1406 }
1407
1408 if (!sl_wifi_is_interface_up(interface)) {
1409 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1410 }
1411
1412 sl_status_t status = SL_STATUS_OK;
1413 sl_si91x_req_rx_stats_t rx_stats = { 0 };
1414
1415 // Configure to start RX stats
1416 rx_stats.start[0] = START_STATISTICS_REPORT;
1417 // Copy the channel number
1418 memcpy(rx_stats.channel, &channel.channel, sizeof(rx_stats.channel));
1419 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_RX_STATS,
1420 SI91X_WLAN_CMD,
1421 &rx_stats,
1422 sizeof(rx_stats),
1423 SL_SI91X_RETURN_IMMEDIATELY,
1424 NULL,
1425 NULL);
1426 VERIFY_STATUS_AND_RETURN(status);
1427 return status;
1428 }
1429
sl_wifi_stop_statistic_report(sl_wifi_interface_t interface)1430 sl_status_t sl_wifi_stop_statistic_report(sl_wifi_interface_t interface)
1431 {
1432 if (!device_initialized) {
1433 return SL_STATUS_NOT_INITIALIZED;
1434 }
1435
1436 if (!sl_wifi_is_interface_up(interface)) {
1437 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1438 }
1439
1440 sl_si91x_req_rx_stats_t rx_stats = { 0 };
1441
1442 // Configure to stop RX stats
1443 rx_stats.start[0] = STOP_STATISTICS_REPORT;
1444
1445 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_RX_STATS,
1446 SI91X_WLAN_CMD,
1447 &rx_stats,
1448 sizeof(rx_stats),
1449 SL_SI91X_WAIT_FOR_COMMAND_RESPONSE,
1450 NULL,
1451 NULL);
1452 VERIFY_STATUS_AND_RETURN(status);
1453 return status;
1454 }
1455
sl_wifi_set_performance_profile(const sl_wifi_performance_profile_t * profile)1456 sl_status_t sl_wifi_set_performance_profile(const sl_wifi_performance_profile_t *profile)
1457 {
1458 sl_status_t status;
1459 sl_si91x_performance_profile_t selected_coex_profile_mode = { 0 };
1460 sl_wifi_performance_profile_t current_wifi_profile_mode = { 0 };
1461
1462 if (!device_initialized) {
1463 return SL_STATUS_NOT_INITIALIZED;
1464 }
1465
1466 SL_WIFI_ARGS_CHECK_NULL_POINTER(profile);
1467
1468 if (profile->profile > DEEP_SLEEP_WITH_RAM_RETENTION) {
1469 return SL_STATUS_INVALID_MODE;
1470 }
1471
1472 // Take backup of current wifi profile
1473 get_wifi_current_performance_profile(¤t_wifi_profile_mode);
1474
1475 // Send the power save command for the requested profile
1476 status = sli_si91x_send_power_save_request(profile, NULL);
1477 if (status != SL_STATUS_OK) {
1478 save_wifi_current_performance_profile(¤t_wifi_profile_mode);
1479 return status;
1480 }
1481 get_coex_performance_profile(&selected_coex_profile_mode);
1482
1483 // Set device_initialized as false since RAM of module will be not retained
1484 // in ULTRA_POWER_SAVE and module needs to be started from init again
1485 if (selected_coex_profile_mode == DEEP_SLEEP_WITHOUT_RAM_RETENTION) {
1486 device_initialized = false;
1487
1488 #ifdef SLI_SI91X_MCU_INTERFACE
1489 // In soc mode m4 does not get the card ready for next init after deinit, but if device in DEEP_SLEEP_WITHOUT_RAM_RETENTION mode, m4 should wait for card ready for next init
1490 set_card_ready_required(true);
1491 #endif
1492 reset_coex_current_performance_profile();
1493 }
1494
1495 return SL_STATUS_OK;
1496 }
1497
sl_wifi_get_performance_profile(sl_wifi_performance_profile_t * profile)1498 sl_status_t sl_wifi_get_performance_profile(sl_wifi_performance_profile_t *profile)
1499 {
1500 if (!device_initialized) {
1501 return SL_STATUS_NOT_INITIALIZED;
1502 }
1503
1504 get_wifi_current_performance_profile(profile);
1505 return SL_STATUS_OK;
1506 }
1507
sl_wifi_get_default_interface(void)1508 sl_wifi_interface_t sl_wifi_get_default_interface(void)
1509 {
1510 return default_interface;
1511 }
1512
sl_wifi_set_default_interface(sl_wifi_interface_t interface)1513 void sl_wifi_set_default_interface(sl_wifi_interface_t interface)
1514 {
1515 default_interface = interface;
1516 }
1517
sl_wifi_deinit(void)1518 sl_status_t sl_wifi_deinit(void)
1519 {
1520 sl_status_t status;
1521 bg_enabled = false;
1522 reset_coex_current_performance_profile();
1523 reset_max_tx_power();
1524 reset_ap_configuration();
1525 reset_sl_wifi_rate();
1526 memset(&advanced_scan_configuration, 0, sizeof(sl_wifi_advanced_scan_configuration_t));
1527 status = sl_si91x_driver_deinit();
1528 sli_wifi_flush_scan_results_database();
1529
1530 SLI_NETWORK_CLEANUP_HANDLER();
1531
1532 return status;
1533 }
1534
1535 // 5GHz interface is currently not supported for Si91x
sl_wifi_is_interface_up(sl_wifi_interface_t interface)1536 bool sl_wifi_is_interface_up(sl_wifi_interface_t interface)
1537 {
1538 switch (interface) {
1539 case SL_WIFI_CLIENT_INTERFACE:
1540 return interface_is_up[SL_WIFI_CLIENT_2_4GHZ_INTERFACE_INDEX]
1541 | interface_is_up[SL_WIFI_CLIENT_5GHZ_INTERFACE_INDEX];
1542 case SL_WIFI_AP_INTERFACE:
1543 return interface_is_up[SL_WIFI_AP_2_4GHZ_INTERFACE_INDEX] | interface_is_up[SL_WIFI_AP_5GHZ_INTERFACE_INDEX];
1544 case SL_WIFI_CLIENT_2_4GHZ_INTERFACE:
1545 return interface_is_up[SL_WIFI_CLIENT_2_4GHZ_INTERFACE_INDEX];
1546 case SL_WIFI_AP_2_4GHZ_INTERFACE:
1547 return interface_is_up[SL_WIFI_AP_2_4GHZ_INTERFACE_INDEX];
1548 case SL_WIFI_CLIENT_5GHZ_INTERFACE:
1549 return interface_is_up[SL_WIFI_CLIENT_5GHZ_INTERFACE_INDEX];
1550 case SL_WIFI_AP_5GHZ_INTERFACE:
1551 return interface_is_up[SL_WIFI_AP_5GHZ_INTERFACE_INDEX];
1552 case SL_WIFI_2_4GHZ_INTERFACE:
1553 return interface_is_up[SL_WIFI_CLIENT_2_4GHZ_INTERFACE_INDEX]
1554 | interface_is_up[SL_WIFI_AP_2_4GHZ_INTERFACE_INDEX];
1555 case SL_WIFI_5GHZ_INTERFACE:
1556 return interface_is_up[SL_WIFI_CLIENT_5GHZ_INTERFACE_INDEX] | interface_is_up[SL_WIFI_AP_5GHZ_INTERFACE_INDEX];
1557 case SL_WIFI_ALL_INTERFACES:
1558 return interface_is_up[SL_WIFI_CLIENT_5GHZ_INTERFACE_INDEX] | interface_is_up[SL_WIFI_AP_5GHZ_INTERFACE_INDEX]
1559 | interface_is_up[SL_WIFI_CLIENT_2_4GHZ_INTERFACE_INDEX]
1560 | interface_is_up[SL_WIFI_AP_2_4GHZ_INTERFACE_INDEX];
1561 case SL_WIFI_TRANSCEIVER_INTERFACE:
1562 return interface_is_up[SL_WIFI_TRANSCEIVER_INTERFACE_INDEX];
1563 default:
1564 return false;
1565 }
1566 }
1567
sl_wifi_set_certificate_with_index(uint8_t certificate_type,uint8_t certificate_index,uint8_t * buffer,uint32_t certificate_length)1568 sl_status_t sl_wifi_set_certificate_with_index(uint8_t certificate_type,
1569 uint8_t certificate_index,
1570 uint8_t *buffer,
1571 uint32_t certificate_length)
1572 {
1573 return sl_si91x_wifi_set_certificate_index(certificate_type, certificate_index, buffer, certificate_length);
1574 }
1575
sl_wifi_set_certificate(uint8_t certificate_type,const uint8_t * buffer,uint32_t certificate_length)1576 sl_status_t sl_wifi_set_certificate(uint8_t certificate_type, const uint8_t *buffer, uint32_t certificate_length)
1577 {
1578 return sl_si91x_wifi_set_certificate_index(certificate_type, 0, buffer, certificate_length);
1579 }
1580
sl_wifi_set_transmit_rate(sl_wifi_interface_t interface,sl_wifi_rate_protocol_t rate_protocol,sl_wifi_rate_t mask)1581 sl_status_t sl_wifi_set_transmit_rate(sl_wifi_interface_t interface,
1582 sl_wifi_rate_protocol_t rate_protocol,
1583 sl_wifi_rate_t mask)
1584 {
1585 if (!device_initialized) {
1586 return SL_STATUS_NOT_INITIALIZED;
1587 }
1588
1589 if (sl_wifi_is_interface_up(interface)) {
1590 if (interface == SL_WIFI_AP_INTERFACE) {
1591 return SL_STATUS_WIFI_UNSUPPORTED;
1592 }
1593 } else {
1594 if (interface == SL_WIFI_CLIENT_INTERFACE) {
1595 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1596 }
1597 }
1598
1599 switch (rate_protocol) {
1600 case SL_WIFI_RATE_PROTOCOL_B_ONLY: {
1601 if (mask < SL_WIFI_RATE_11B_MIN || mask > SL_WIFI_RATE_11B_MAX) {
1602 return SL_STATUS_INVALID_CONFIGURATION;
1603 }
1604 break;
1605 }
1606 case SL_WIFI_RATE_PROTOCOL_G_ONLY: {
1607 if (mask < SL_WIFI_RATE_11G_MIN || mask > SL_WIFI_RATE_11G_MAX) {
1608 return SL_STATUS_INVALID_CONFIGURATION;
1609 }
1610 break;
1611 }
1612 case SL_WIFI_RATE_PROTOCOL_N_ONLY: {
1613 if (mask < SL_WIFI_RATE_11N_MIN || mask > SL_WIFI_RATE_11N_MAX) {
1614 return SL_STATUS_INVALID_CONFIGURATION;
1615 }
1616 break;
1617 }
1618 case SL_WIFI_RATE_PROTOCOL_AC_ONLY: {
1619 return SL_STATUS_NOT_SUPPORTED;
1620 }
1621 case SL_WIFI_RATE_PROTOCOL_AX_ONLY: {
1622 if (mask < SL_WIFI_RATE_11AX_MIN || mask > SL_WIFI_RATE_11AX_MAX) {
1623 return SL_STATUS_INVALID_CONFIGURATION;
1624 }
1625 break;
1626 }
1627 case SL_WIFI_RATE_PROTOCOL_AUTO: {
1628 if (mask != SL_WIFI_AUTO_RATE) {
1629 return SL_STATUS_INVALID_CONFIGURATION;
1630 }
1631 break;
1632 }
1633 default: {
1634 return SL_STATUS_INVALID_CONFIGURATION;
1635 }
1636 }
1637
1638 return save_sl_wifi_rate(mask);
1639 }
1640
sl_wifi_get_transmit_rate(sl_wifi_interface_t interface,sl_wifi_rate_protocol_t * rate_protocol,sl_wifi_rate_t * mask)1641 sl_status_t sl_wifi_get_transmit_rate(sl_wifi_interface_t interface,
1642 sl_wifi_rate_protocol_t *rate_protocol,
1643 sl_wifi_rate_t *mask)
1644 {
1645 if (!device_initialized) {
1646 return SL_STATUS_NOT_INITIALIZED;
1647 }
1648
1649 if (!sl_wifi_is_interface_up(interface)) {
1650 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1651 }
1652
1653 SL_WIFI_ARGS_CHECK_NULL_POINTER(rate_protocol);
1654 SL_WIFI_ARGS_CHECK_NULL_POINTER(mask);
1655
1656 sl_wifi_rate_t transfer_rate;
1657 get_saved_sl_wifi_rate(&transfer_rate);
1658
1659 return get_rate_protocol_and_data_rate(transfer_rate, rate_protocol, mask);
1660 }
1661
sl_wifi_get_ap_client_count(sl_wifi_interface_t interface,uint32_t * client_list_count)1662 sl_status_t sl_wifi_get_ap_client_count(sl_wifi_interface_t interface, uint32_t *client_list_count)
1663 {
1664 sl_wifi_client_info_response_t client_info = { 0 };
1665
1666 SL_WIFI_ARGS_CHECK_NULL_POINTER(client_list_count);
1667
1668 sl_status_t status = sl_wifi_get_ap_client_info(interface, &client_info);
1669
1670 if (status == SL_STATUS_OK) {
1671 memcpy(client_list_count, (uint32_t *)&client_info.client_count, sizeof(uint32_t));
1672 }
1673
1674 return status;
1675 }
1676
sl_wifi_get_ap_client_list(sl_wifi_interface_t interface,uint16_t client_list_count,sl_mac_address_t * client_list)1677 sl_status_t sl_wifi_get_ap_client_list(sl_wifi_interface_t interface,
1678 uint16_t client_list_count,
1679 sl_mac_address_t *client_list)
1680 {
1681 sl_wifi_client_info_response_t client_info = { 0 };
1682
1683 sl_status_t status = sl_wifi_get_ap_client_info(interface, &client_info);
1684
1685 if (status == SL_STATUS_OK) {
1686 for (uint16_t station_info_index = 0;
1687 station_info_index < client_info.client_count && station_info_index < client_list_count;
1688 station_info_index++) {
1689 memcpy(client_list[station_info_index].octet,
1690 client_info.client_info[station_info_index].mac_adddress.octet,
1691 sizeof(sl_mac_address_t));
1692 }
1693 }
1694
1695 return status;
1696 }
sl_wifi_generate_wps_pin(sl_wifi_wps_pin_t * wps_pin)1697 sl_status_t sl_wifi_generate_wps_pin(sl_wifi_wps_pin_t *wps_pin)
1698 {
1699 sl_status_t status = SL_STATUS_OK;
1700 sl_wifi_buffer_t *buffer = NULL;
1701 sl_si91x_packet_t *packet = NULL;
1702 sl_si91x_wps_method_request_t wps_method_request = { 0 };
1703
1704 SL_WIFI_ARGS_CHECK_NULL_POINTER(wps_pin);
1705
1706 if (!device_initialized) {
1707 return SL_STATUS_NOT_INITIALIZED;
1708 }
1709
1710 // Set configuration to generate new WPS pin
1711 wps_method_request.wps_method = SI91X_SET_WPS_METHOD_PIN;
1712 wps_method_request.generate_pin = SI91X_SET_WPS_GENERATE_PIN;
1713
1714 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_WPS_METHOD,
1715 SI91X_WLAN_CMD,
1716 &wps_method_request,
1717 sizeof(sl_si91x_wps_method_request_t),
1718 SL_SI91X_WAIT_FOR_COMMAND_RESPONSE,
1719 NULL,
1720 &buffer);
1721 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
1722 sl_si91x_host_free_buffer(buffer);
1723 }
1724 VERIFY_STATUS_AND_RETURN(status);
1725
1726 packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
1727 if (packet->length > 0) {
1728 memcpy(wps_pin->digits, packet->data, sizeof(sl_wifi_wps_pin_t));
1729 }
1730
1731 sl_si91x_host_free_buffer(buffer);
1732 return status;
1733 }
1734
sl_wifi_start_wps(sl_wifi_interface_t interface,sl_wifi_wps_mode_t mode,const sl_wifi_wps_pin_t * optional_wps_pin)1735 sl_status_t sl_wifi_start_wps(sl_wifi_interface_t interface,
1736 sl_wifi_wps_mode_t mode,
1737 const sl_wifi_wps_pin_t *optional_wps_pin)
1738 {
1739 UNUSED_PARAMETER(optional_wps_pin);
1740
1741 if (!device_initialized) {
1742 return SL_STATUS_NOT_INITIALIZED;
1743 }
1744
1745 if (mode != SL_WIFI_WPS_PUSH_BUTTON_MODE || (interface & SL_WIFI_AP_INTERFACE) == 0) {
1746 return SL_STATUS_NOT_SUPPORTED;
1747 }
1748
1749 if (!sl_wifi_is_interface_up(interface)) {
1750 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1751 }
1752
1753 sl_status_t status;
1754 sl_si91x_join_request_t wps_button_press_request = { 0 };
1755 sl_wifi_ap_configuration_t ap_configuration = { 0 };
1756
1757 get_saved_ap_configuration(&ap_configuration);
1758 status = get_configured_join_request(SL_WIFI_AP_INTERFACE, &ap_configuration, &wps_button_press_request);
1759
1760 VERIFY_STATUS_AND_RETURN(status);
1761 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_JOIN,
1762 SI91X_WLAN_CMD,
1763 &wps_button_press_request,
1764 sizeof(wps_button_press_request),
1765 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
1766 NULL,
1767 NULL);
1768
1769 VERIFY_STATUS_AND_RETURN(status);
1770 return status;
1771 }
sl_wifi_set_roam_configuration(sl_wifi_interface_t interface,sl_wifi_roam_configuration_t * roam_configuration)1772 sl_status_t sl_wifi_set_roam_configuration(sl_wifi_interface_t interface,
1773 sl_wifi_roam_configuration_t *roam_configuration)
1774 {
1775 sl_si91x_req_roam_params_t roam_param_request = { 0 };
1776
1777 if (!device_initialized) {
1778 return SL_STATUS_NOT_INITIALIZED;
1779 }
1780
1781 if (interface & SL_WIFI_AP_INTERFACE) {
1782 return SL_STATUS_NOT_SUPPORTED;
1783 }
1784
1785 if (!sl_wifi_is_interface_up(interface)) {
1786 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1787 }
1788
1789 if (roam_configuration->trigger_level != SL_WIFI_NEVER_ROAM) {
1790 roam_param_request.roam_enable = ALWAYS_ROAM;
1791 }
1792
1793 roam_param_request.roam_threshold = -1 * roam_configuration->trigger_level;
1794 roam_param_request.roam_hysteresis = roam_configuration->trigger_level_change;
1795
1796 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_ROAM_PARAMS,
1797 SI91X_WLAN_CMD,
1798 &roam_param_request,
1799 sizeof(sl_si91x_req_roam_params_t),
1800 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
1801 NULL,
1802 NULL);
1803
1804 VERIFY_STATUS_AND_RETURN(status);
1805 return status;
1806 }
1807
sl_wifi_set_advanced_scan_configuration(const sl_wifi_advanced_scan_configuration_t * configuration)1808 sl_status_t sl_wifi_set_advanced_scan_configuration(const sl_wifi_advanced_scan_configuration_t *configuration)
1809 {
1810 SL_WIFI_ARGS_CHECK_NULL_POINTER(configuration);
1811
1812 if (!device_initialized) {
1813 return SL_STATUS_NOT_INITIALIZED;
1814 }
1815
1816 memcpy(&advanced_scan_configuration, configuration, sizeof(sl_wifi_advanced_scan_configuration_t));
1817
1818 return SL_STATUS_OK;
1819 }
1820
sl_wifi_get_advanced_scan_configuration(sl_wifi_advanced_scan_configuration_t * configuration)1821 sl_status_t sl_wifi_get_advanced_scan_configuration(sl_wifi_advanced_scan_configuration_t *configuration)
1822 {
1823 SL_WIFI_ARGS_CHECK_NULL_POINTER(configuration);
1824
1825 if (!device_initialized) {
1826 return SL_STATUS_NOT_INITIALIZED;
1827 }
1828
1829 memcpy(configuration, &advanced_scan_configuration, sizeof(sl_wifi_advanced_scan_configuration_t));
1830
1831 return SL_STATUS_OK;
1832 }
1833
sl_wifi_stop_scan(sl_wifi_interface_t interface)1834 sl_status_t sl_wifi_stop_scan(sl_wifi_interface_t interface)
1835 {
1836 sl_status_t status = SL_STATUS_OK;
1837 sl_si91x_req_bg_scan_t scan_request = { 0 };
1838
1839 if (!device_initialized) {
1840 return SL_STATUS_NOT_INITIALIZED;
1841 }
1842
1843 if (interface & SL_WIFI_AP_INTERFACE) {
1844 return SL_STATUS_NOT_SUPPORTED;
1845 }
1846
1847 if (!sl_wifi_is_interface_up(interface)) {
1848 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1849 }
1850
1851 // Once stop_scan() support for foreground scan is available, "bg_enabled" should be removed.
1852 if (bg_enabled == true) {
1853 scan_request.bgscan_enable = SI91X_BG_SCAN_DISABLE;
1854 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_BG_SCAN,
1855 SI91X_WLAN_CMD,
1856 &scan_request,
1857 sizeof(sl_si91x_req_bg_scan_t),
1858 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
1859 NULL,
1860 NULL);
1861 VERIFY_STATUS_AND_RETURN(status);
1862 bg_enabled = false;
1863 } else {
1864 return SL_STATUS_NOT_SUPPORTED;
1865 }
1866
1867 return status;
1868 }
1869
sl_wifi_set_ap_configuration(sl_wifi_interface_t interface,const sl_wifi_ap_configuration_t * configuration)1870 sl_status_t sl_wifi_set_ap_configuration(sl_wifi_interface_t interface, const sl_wifi_ap_configuration_t *configuration)
1871 {
1872 UNUSED_PARAMETER(interface);
1873 UNUSED_PARAMETER(configuration);
1874 if (!device_initialized) {
1875 return SL_STATUS_NOT_INITIALIZED;
1876 }
1877 //Firmware unable to configure the ap configuration of a running AP interface
1878 return SL_STATUS_NOT_SUPPORTED;
1879 }
1880
sl_wifi_get_ap_configuration(sl_wifi_interface_t interface,sl_wifi_ap_configuration_t * configuration)1881 sl_status_t sl_wifi_get_ap_configuration(sl_wifi_interface_t interface, sl_wifi_ap_configuration_t *configuration)
1882 {
1883 if (!device_initialized) {
1884 return SL_STATUS_NOT_INITIALIZED;
1885 }
1886
1887 SL_VERIFY_POINTER_OR_RETURN(configuration, SL_STATUS_NULL_POINTER);
1888
1889 if (!sl_wifi_is_interface_up(interface)) {
1890 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1891 }
1892
1893 sl_wifi_ap_configuration_t saved_ap_configuration = { 0 };
1894 get_saved_ap_configuration(&saved_ap_configuration);
1895
1896 memcpy(configuration, &saved_ap_configuration, sizeof(sl_wifi_ap_configuration_t));
1897
1898 return SL_STATUS_OK;
1899 }
1900
sl_wifi_reconfigure_ap(sl_wifi_interface_t interface,sl_si91x_ap_reconfiguration_t config)1901 sl_status_t sl_wifi_reconfigure_ap(sl_wifi_interface_t interface, sl_si91x_ap_reconfiguration_t config)
1902 {
1903 sl_status_t status = SL_STATUS_OK;
1904
1905 if (!device_initialized) {
1906 return SL_STATUS_NOT_INITIALIZED;
1907 }
1908
1909 if (interface & SL_WIFI_CLIENT_INTERFACE) {
1910 return SL_STATUS_NOT_SUPPORTED;
1911 }
1912
1913 if (!sl_wifi_is_interface_up(interface)) {
1914 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1915 }
1916
1917 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_BEACON_STOP,
1918 SI91X_WLAN_CMD,
1919 &config,
1920 sizeof(sl_si91x_ap_reconfiguration_t),
1921 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
1922 NULL,
1923 NULL);
1924 VERIFY_STATUS_AND_RETURN(status);
1925
1926 return status;
1927 }
1928
sl_wifi_test_client_configuration(sl_wifi_interface_t interface,const sl_wifi_client_configuration_t * ap,uint32_t timeout_ms)1929 sl_status_t sl_wifi_test_client_configuration(sl_wifi_interface_t interface,
1930 const sl_wifi_client_configuration_t *ap,
1931 uint32_t timeout_ms)
1932 {
1933 sl_status_t status = sl_wifi_connect(interface, ap, timeout_ms);
1934 VERIFY_STATUS_AND_RETURN(status);
1935
1936 status = sl_wifi_disconnect(SL_WIFI_CLIENT_INTERFACE);
1937 VERIFY_STATUS_AND_RETURN(status);
1938
1939 return SL_STATUS_OK;
1940 }
1941
sl_wifi_send_raw_data_frame(sl_wifi_interface_t interface,const void * data,uint16_t data_length)1942 sl_status_t sl_wifi_send_raw_data_frame(sl_wifi_interface_t interface, const void *data, uint16_t data_length)
1943 {
1944 if (!device_initialized) {
1945 return SL_STATUS_NOT_INITIALIZED;
1946 }
1947
1948 if (!sl_wifi_is_interface_up(interface)) {
1949 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
1950 }
1951
1952 SL_VERIFY_POINTER_OR_RETURN(data, SL_STATUS_NULL_POINTER);
1953
1954 if (data_length == 0) {
1955 return SL_STATUS_INVALID_PARAMETER;
1956 }
1957 return sl_si91x_driver_raw_send_command(RSI_SEND_RAW_DATA, data, data_length, RSI_SEND_RAW_DATA_RESPONSE_WAIT_TIME);
1958 }
1959
sl_wifi_enable_target_wake_time(sl_wifi_twt_request_t * twt_req)1960 sl_status_t sl_wifi_enable_target_wake_time(sl_wifi_twt_request_t *twt_req)
1961 {
1962 if (!twt_req->twt_enable) {
1963 return SL_STATUS_INVALID_PARAMETER;
1964 }
1965 if (twt_req->twt_flow_id > MAX_FLOW_ID) {
1966 return SL_STATUS_INVALID_PARAMETER;
1967 }
1968 if (twt_req->wake_int_exp > MAX_WAKE_INTERVAL_EXPONENT) {
1969 return SL_STATUS_INVALID_PARAMETER;
1970 }
1971 if (twt_req->wake_int_exp_tol > MAX_WAKE_INTERVAL_EXPONENT_TOLERANCE) {
1972 return SL_STATUS_INVALID_PARAMETER;
1973 }
1974 if (twt_req->wake_duration_unit > MAX_WAKE_DURATION_UNIT) {
1975 return SL_STATUS_INVALID_PARAMETER;
1976 }
1977 if (twt_req->un_announced_twt > 1 || twt_req->triggered_twt > 1 || twt_req->restrict_tx_outside_tsp > 1) {
1978 return SL_STATUS_INVALID_PARAMETER;
1979 }
1980 if (twt_req->twt_retry_limit > MAX_TWT_RETRY_LIMIT) {
1981 return SL_STATUS_INVALID_PARAMETER;
1982 }
1983 if (twt_req->twt_retry_interval < MIN_TWT_RETRY_INTERVAL) {
1984 return SL_STATUS_INVALID_PARAMETER;
1985 }
1986 if (twt_req->req_type > MAX_TWT_REQ_TYPE) {
1987 return SL_STATUS_INVALID_PARAMETER;
1988 }
1989 if ((twt_req->req_type != REQUEST_TWT)
1990 && (twt_req->wake_duration == 0 || twt_req->wake_int_mantissa == 0
1991 || ((uint32_t)twt_req->wake_duration
1992 * (uint32_t)(twt_req->wake_duration_unit ? TWT_WAKE_DURATION_UNIT_1024TU : TWT_WAKE_DURATION_UNIT_256TU))
1993 > ((uint64_t)((twt_req->wake_int_mantissa) * ((uint64_t)1 << twt_req->wake_int_exp))))) {
1994 return SL_STATUS_INVALID_PARAMETER;
1995 }
1996 if ((twt_req->twt_channel != 0) || (twt_req->twt_protection != 0) || (twt_req->implicit_twt != 1)) {
1997 return SL_STATUS_INVALID_PARAMETER;
1998 }
1999 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_TWT_PARAMS,
2000 SI91X_WLAN_CMD,
2001 twt_req,
2002 sizeof(sl_wifi_twt_request_t),
2003 SL_SI91X_WAIT_FOR(35000),
2004 NULL,
2005 NULL);
2006 VERIFY_STATUS_AND_RETURN(status);
2007 return status;
2008 }
2009
sl_wifi_target_wake_time_auto_selection(sl_wifi_twt_selection_t * twt_auto_request)2010 sl_status_t sl_wifi_target_wake_time_auto_selection(sl_wifi_twt_selection_t *twt_auto_request)
2011 {
2012 if ((twt_auto_request->twt_enable != 0) && (twt_auto_request->twt_enable != 1)) {
2013 return SL_STATUS_INVALID_PARAMETER;
2014 }
2015 if ((twt_auto_request->twt_enable == 1)
2016 && ((twt_auto_request->rx_latency > MAX_TX_AND_RX_LATENCY_LIMIT)
2017 || (twt_auto_request->tx_latency > MAX_TX_AND_RX_LATENCY_LIMIT))) {
2018 return SL_STATUS_INVALID_PARAMETER;
2019 }
2020 twt_auto_request->rx_latency = (twt_auto_request->rx_latency == 0) ? 2000 : twt_auto_request->rx_latency;
2021 if ((twt_auto_request->rx_latency < 2000)
2022 || (twt_auto_request->average_tx_throughput > (DEVICE_AVERAGE_THROUGHPUT / 2))) {
2023 return SL_STATUS_INVALID_PARAMETER;
2024 }
2025 if ((twt_auto_request->tx_latency < 200) && (twt_auto_request->tx_latency != 0)) {
2026 return SL_STATUS_INVALID_PARAMETER;
2027 }
2028 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_TWT_AUTO_CONFIG,
2029 SI91X_WLAN_CMD,
2030 twt_auto_request,
2031 sizeof(sl_wifi_twt_selection_t),
2032 SL_SI91X_WAIT_FOR(35000),
2033 NULL,
2034 NULL);
2035 VERIFY_STATUS_AND_RETURN(status);
2036 return status;
2037 }
2038
sl_wifi_disable_target_wake_time(sl_wifi_twt_request_t * twt_req)2039 sl_status_t sl_wifi_disable_target_wake_time(sl_wifi_twt_request_t *twt_req)
2040 {
2041 if ((!twt_req->twt_enable) && ((twt_req->twt_flow_id == 0xFF) || (twt_req->twt_flow_id <= 7))) {
2042 sl_status_t status = sl_si91x_driver_send_command(RSI_WLAN_REQ_TWT_PARAMS,
2043 SI91X_WLAN_CMD,
2044 twt_req,
2045 sizeof(sl_wifi_twt_request_t),
2046 SL_SI91X_WAIT_FOR(35000),
2047 NULL,
2048 NULL);
2049 VERIFY_STATUS_AND_RETURN(status);
2050 return status;
2051 }
2052
2053 return SL_STATUS_INVALID_PARAMETER;
2054 }
2055
sl_wifi_reschedule_twt(uint8_t flow_id,sl_wifi_reschedule_twt_action_t twt_action,uint64_t suspend_duration)2056 sl_status_t sl_wifi_reschedule_twt(uint8_t flow_id,
2057 sl_wifi_reschedule_twt_action_t twt_action,
2058 uint64_t suspend_duration)
2059 {
2060 if (!device_initialized) {
2061 return SL_STATUS_NOT_INITIALIZED;
2062 }
2063 if (flow_id > MAX_FLOW_ID) {
2064 return SL_STATUS_INVALID_PARAMETER;
2065 }
2066 if ((twt_action == SL_WIFI_SUSPEND_INDEFINITELY || twt_action == SL_WIFI_RESUME_IMMEDIATELY)
2067 && suspend_duration > 0) {
2068 return SL_STATUS_INVALID_PARAMETER;
2069 }
2070 if (twt_action == SL_WIFI_SUSPEND_FOR_DURATION
2071 && (suspend_duration < 1 || suspend_duration > MAX_TWT_SUSPEND_DURATION)) {
2072 return SL_STATUS_INVALID_PARAMETER;
2073 }
2074 if (twt_action != SL_WIFI_SUSPEND_INDEFINITELY && twt_action != SL_WIFI_SUSPEND_FOR_DURATION
2075 && twt_action != SL_WIFI_RESUME_IMMEDIATELY) {
2076 return SL_STATUS_INVALID_PARAMETER;
2077 }
2078
2079 sl_wifi_reschedule_twt_config_t reschedule_twt_config = { 0 };
2080 reschedule_twt_config.flow_id = flow_id;
2081 reschedule_twt_config.twt_action = twt_action;
2082 reschedule_twt_config.suspend_duration = suspend_duration;
2083 sl_status_t status = sl_si91x_driver_send_command(SL_WIFI_REQ_RESCHEDULE_TWT,
2084 SI91X_WLAN_CMD,
2085 &reschedule_twt_config,
2086 sizeof(sl_wifi_reschedule_twt_config_t),
2087 SL_SI91X_WAIT_FOR(35000),
2088 NULL,
2089 NULL);
2090 VERIFY_STATUS_AND_RETURN(status);
2091 return status;
2092 }
2093
sl_wifi_filter_broadcast(uint16_t beacon_drop_threshold,uint8_t filter_bcast_in_tim,uint8_t filter_bcast_tim_till_next_cmd)2094 sl_status_t sl_wifi_filter_broadcast(uint16_t beacon_drop_threshold,
2095 uint8_t filter_bcast_in_tim,
2096 uint8_t filter_bcast_tim_till_next_cmd)
2097 {
2098 sl_status_t status = SL_STATUS_OK;
2099 sl_si91x_request_wlan_filter_broadcast_t sl_filter_bcast = { 0 };
2100 sl_filter_bcast.beacon_drop_threshold[0] = beacon_drop_threshold & 0x00FF;
2101 sl_filter_bcast.beacon_drop_threshold[1] = (beacon_drop_threshold >> 8) & 0x00FF;
2102 sl_filter_bcast.filter_bcast_in_tim = filter_bcast_in_tim;
2103 sl_filter_bcast.filter_bcast_tim_till_next_cmd = filter_bcast_tim_till_next_cmd;
2104
2105 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_FILTER_BCAST_PACKETS,
2106 SI91X_WLAN_CMD,
2107 &sl_filter_bcast,
2108 sizeof(sl_si91x_request_wlan_filter_broadcast_t),
2109 SL_SI91X_WAIT_FOR(30100),
2110 NULL,
2111 NULL);
2112 VERIFY_STATUS_AND_RETURN(status);
2113 return status;
2114 }
2115
sl_wifi_update_gain_table(uint8_t band,uint8_t bandwidth,uint8_t * payload,uint16_t payload_length)2116 sl_status_t sl_wifi_update_gain_table(uint8_t band, uint8_t bandwidth, uint8_t *payload, uint16_t payload_length)
2117 {
2118 sl_status_t status = SL_STATUS_OK;
2119 sl_si91x_gain_table_info_t *sl_gain_table_info = malloc(sizeof(sl_si91x_gain_table_info_t) + payload_length);
2120 if (sl_gain_table_info == NULL) {
2121 return SL_STATUS_ALLOCATION_FAILED;
2122 }
2123 sl_gain_table_info->band = band;
2124 sl_gain_table_info->bandwidth = bandwidth;
2125 sl_gain_table_info->size = payload_length;
2126 sl_gain_table_info->reserved = 0;
2127
2128 memcpy(sl_gain_table_info->gain_table, payload, payload_length);
2129 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_GAIN_TABLE,
2130 SI91X_WLAN_CMD,
2131 sl_gain_table_info,
2132 sizeof(sl_si91x_gain_table_info_t) + (sl_gain_table_info->size),
2133 SL_SI91X_WAIT_FOR(30100),
2134 NULL,
2135 NULL);
2136 free(sl_gain_table_info);
2137 VERIFY_STATUS_AND_RETURN(status);
2138 return status;
2139 }
2140
sl_wifi_set_11ax_config(uint8_t guard_interval)2141 sl_status_t sl_wifi_set_11ax_config(uint8_t guard_interval)
2142 {
2143 sl_status_t status = SL_STATUS_OK;
2144 #if !(SLI_SI91X_CONFIG_WIFI6_PARAMS)
2145 return SL_STATUS_NOT_SUPPORTED;
2146 #endif
2147 sl_si91x_11ax_config_params_t config_11ax_params = { 0 };
2148 config_11ax_params.guard_interval = guard_interval;
2149 config_11ax_params.nominal_pe = NOMINAL_PE;
2150 config_11ax_params.dcm_enable = DCM_ENABLE;
2151 config_11ax_params.ldpc_enable = LDPC_ENABLE;
2152 config_11ax_params.ng_cb_enable = NG_CB_ENABLE;
2153 config_11ax_params.ng_cb_values = NG_CB_VALUES;
2154 config_11ax_params.uora_enable = UORA_ENABLE;
2155 config_11ax_params.trigger_rsp_ind = TRIGGER_RESP_IND;
2156 config_11ax_params.ipps_valid_value = IPPS_VALID_VALUE;
2157 config_11ax_params.tx_only_on_ap_trig = TX_ONLY_ON_AP_TRIG;
2158 config_11ax_params.twt_support = SLI_SI91X_ENABLE_TWT_FEATURE;
2159 config_11ax_params.config_er_su = CONFIG_ER_SU;
2160 config_11ax_params.disable_su_beamformee_support = SLI_SI91X_DISABLE_SU_BEAMFORMEE_SUPPORT;
2161
2162 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_11AX_PARAMS,
2163 SI91X_WLAN_CMD,
2164 &config_11ax_params,
2165 sizeof(config_11ax_params),
2166 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
2167 NULL,
2168 NULL);
2169 VERIFY_STATUS_AND_RETURN(status);
2170 return status;
2171 }
2172
sl_wifi_set_listen_interval(sl_wifi_interface_t interface,sl_wifi_listen_interval_t listen_interval)2173 sl_status_t sl_wifi_set_listen_interval(sl_wifi_interface_t interface, sl_wifi_listen_interval_t listen_interval)
2174 {
2175 UNUSED_PARAMETER(interface);
2176
2177 if (!device_initialized) {
2178 return SL_STATUS_NOT_INITIALIZED;
2179 }
2180
2181 sl_si91x_set_listen_interval(listen_interval.listen_interval);
2182
2183 return SL_STATUS_OK;
2184 }
2185
sl_wifi_get_listen_interval(sl_wifi_interface_t interface,sl_wifi_listen_interval_t * listen_interval)2186 sl_status_t sl_wifi_get_listen_interval(sl_wifi_interface_t interface, sl_wifi_listen_interval_t *listen_interval)
2187 {
2188 if (!device_initialized) {
2189 return SL_STATUS_NOT_INITIALIZED;
2190 }
2191
2192 if (!sl_wifi_is_interface_up(interface)) {
2193 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
2194 }
2195
2196 SL_WIFI_ARGS_CHECK_NULL_POINTER(listen_interval);
2197
2198 listen_interval->listen_interval = sl_si91x_get_listen_interval();
2199
2200 return SL_STATUS_OK;
2201 }
2202
sl_wifi_enable_monitor_mode(sl_wifi_interface_t interface)2203 sl_status_t sl_wifi_enable_monitor_mode(sl_wifi_interface_t interface)
2204 {
2205 UNUSED_PARAMETER(interface);
2206 return SL_STATUS_NOT_SUPPORTED;
2207 }
2208
sl_wifi_disable_monitor_mode(sl_wifi_interface_t interface)2209 sl_status_t sl_wifi_disable_monitor_mode(sl_wifi_interface_t interface)
2210 {
2211 UNUSED_PARAMETER(interface);
2212 return SL_STATUS_NOT_SUPPORTED;
2213 }
2214
sl_wifi_start_p2p_discovery(sl_wifi_interface_t interface,const sl_wifi_p2p_configuration_t * configuration,sl_wifi_credential_id_t credential_id)2215 sl_status_t sl_wifi_start_p2p_discovery(sl_wifi_interface_t interface,
2216 const sl_wifi_p2p_configuration_t *configuration,
2217 sl_wifi_credential_id_t credential_id)
2218 {
2219 UNUSED_PARAMETER(interface);
2220 UNUSED_PARAMETER(configuration);
2221 UNUSED_PARAMETER(credential_id);
2222 return SL_STATUS_NOT_SUPPORTED;
2223 }
2224
sl_wifi_p2p_connect(sl_wifi_interface_t interface,const sl_wifi_p2p_configuration_t * configuration)2225 sl_status_t sl_wifi_p2p_connect(sl_wifi_interface_t interface, const sl_wifi_p2p_configuration_t *configuration)
2226 {
2227 UNUSED_PARAMETER(interface);
2228 UNUSED_PARAMETER(configuration);
2229 return SL_STATUS_NOT_SUPPORTED;
2230 }
2231
sl_wifi_transceiver_set_channel(sl_wifi_interface_t interface,sl_wifi_transceiver_set_channel_t channel)2232 sl_status_t sl_wifi_transceiver_set_channel(sl_wifi_interface_t interface, sl_wifi_transceiver_set_channel_t channel)
2233 {
2234 sl_status_t status = SL_STATUS_OK;
2235 sl_si91x_operation_mode_t opermode;
2236
2237 if (!device_initialized) {
2238 return SL_STATUS_NOT_INITIALIZED;
2239 }
2240
2241 opermode = get_opermode();
2242 if (opermode != SL_SI91X_TRANSCEIVER_MODE) {
2243 SL_DEBUG_LOG("Invalid mode: %d. Command only supported in Wi-Fi transceiver opermode(7)\r\n", opermode);
2244 return SL_STATUS_SI91X_COMMAND_GIVEN_IN_INVALID_STATE;
2245 }
2246
2247 if ((channel.chan_info.channel < 1) || (channel.chan_info.channel > 14)) {
2248 return SL_STATUS_TRANSCEIVER_INVALID_CHANNEL;
2249 }
2250
2251 // User configuration for band and bandwidth are unsupported
2252 channel.chan_info.band = SL_WIFI_BAND_2_4GHZ;
2253 channel.chan_info.bandwidth = SL_WIFI_BANDWIDTH_20MHz;
2254
2255 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_SET_TRANSCEIVER_CHANNEL,
2256 SI91X_WLAN_CMD,
2257 &channel,
2258 sizeof(channel),
2259 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
2260 NULL,
2261 NULL);
2262
2263 VERIFY_STATUS_AND_RETURN(status);
2264
2265 if (interface == SL_WIFI_TRANSCEIVER_INTERFACE) {
2266 interface_is_up[SL_WIFI_TRANSCEIVER_INTERFACE_INDEX] = true;
2267 }
2268
2269 return status;
2270 }
2271
sl_wifi_set_transceiver_parameters(sl_wifi_interface_t interface,sl_wifi_transceiver_parameters_t * params)2272 sl_status_t sl_wifi_set_transceiver_parameters(sl_wifi_interface_t interface, sl_wifi_transceiver_parameters_t *params)
2273 {
2274 sl_status_t status = SL_STATUS_OK;
2275 sl_si91x_operation_mode_t opermode = 0;
2276 sl_wifi_buffer_t *buffer = NULL;
2277 sl_si91x_packet_t *packet = NULL;
2278
2279 if (!device_initialized) {
2280 return SL_STATUS_NOT_INITIALIZED;
2281 }
2282
2283 opermode = get_opermode();
2284 if (opermode != SL_SI91X_TRANSCEIVER_MODE) {
2285 SL_DEBUG_LOG("Invalid mode: %d. Command only supported in Wi-Fi transceiver opermode(7)\r\n", opermode);
2286 return SL_STATUS_SI91X_COMMAND_GIVEN_IN_INVALID_STATE;
2287 }
2288
2289 SL_VERIFY_POINTER_OR_RETURN(params, SL_STATUS_NULL_POINTER);
2290
2291 if (params->set) {
2292 //! Transceiver configurations shall not be changed dynamically
2293 if (sl_wifi_is_interface_up(interface)) {
2294 return SL_STATUS_SI91X_COMMAND_GIVEN_IN_INVALID_STATE;
2295 }
2296
2297 if ((!params->retransmit_count) || (params->retransmit_count > MAX_RETRANSMIT_COUNT)) {
2298 return SL_STATUS_TRANSCEIVER_INVALID_CONFIG;
2299 }
2300 for (uint8_t i = 0; i < 4; i++) {
2301 if ((params->cw_params[i].cwmin > MAX_CW_EXPN_COUNT) || (params->cw_params[i].cwmax > MAX_CW_EXPN_COUNT)
2302 || (params->cw_params[i].aifsn > MAX_AIFSN)) {
2303 return SL_STATUS_TRANSCEIVER_INVALID_CONFIG;
2304 }
2305 }
2306 }
2307
2308 status =
2309 sl_si91x_driver_send_command(RSI_WLAN_REQ_TRANSCEIVER_CONFIG_PARAMS,
2310 SI91X_WLAN_CMD,
2311 params,
2312 sizeof(sl_wifi_transceiver_parameters_t),
2313 params->set ? SL_SI91X_WAIT_FOR_COMMAND_SUCCESS : SL_SI91X_WAIT_FOR_COMMAND_RESPONSE,
2314 NULL,
2315 &buffer);
2316
2317 //! Return if API called to set params. Otherwise, if API called to get params, continue further to copy params received from firmware.
2318 if (params->set) {
2319 return status;
2320 }
2321
2322 if ((status != SL_STATUS_OK) && (buffer != NULL)) {
2323 sl_si91x_host_free_buffer(buffer);
2324 }
2325
2326 VERIFY_STATUS_AND_RETURN(status);
2327
2328 packet = sl_si91x_host_get_buffer_data(buffer, 0, NULL);
2329 if (packet->length > 0) {
2330 memcpy(params, packet->data, sizeof(sl_wifi_transceiver_parameters_t));
2331 }
2332
2333 sl_si91x_host_free_buffer(buffer);
2334 return status;
2335 }
2336
sl_wifi_transceiver_up(sl_wifi_interface_t interface,sl_wifi_transceiver_configuration_t * config)2337 sl_status_t sl_wifi_transceiver_up(sl_wifi_interface_t interface, sl_wifi_transceiver_configuration_t *config)
2338 {
2339 sl_status_t status = SL_STATUS_OK;
2340
2341 if (!device_initialized) {
2342 return SL_STATUS_NOT_INITIALIZED;
2343 }
2344
2345 SL_VERIFY_POINTER_OR_RETURN(config, SL_STATUS_NULL_POINTER);
2346
2347 status = sl_wifi_set_transceiver_parameters(interface, &config->parameters);
2348 if (status != RSI_SUCCESS) {
2349 SL_DEBUG_LOG("\r\nSet transceiver config params failed, error code : 0x%lX\r\n", status);
2350 return status;
2351 } else {
2352 SL_DEBUG_LOG("\r\nSet transceiver config params successful");
2353 }
2354
2355 // Update params.set = 0 to fetch transceiver config params
2356 memset(&config->parameters, 0, sizeof(sl_wifi_transceiver_parameters_t));
2357 status = sl_wifi_set_transceiver_parameters(interface, &config->parameters);
2358 if (status != RSI_SUCCESS) {
2359 SL_DEBUG_LOG("\r\nGet transceiver config params failed, error code : 0x%lX\r\n", status);
2360 } else {
2361 SL_DEBUG_LOG("\r\nTransceiver config params:");
2362 SL_DEBUG_LOG("\r\nRetransmit count: %d", config->parameters.retransmit_count);
2363 for (uint8_t i = 0; i < 4; i++) {
2364 SL_DEBUG_LOG("\r\nAC index[%d] - cwmin: %d, cwmax: %d, aifsn: %d",
2365 i,
2366 config->parameters.cw_params[i].cwmin,
2367 config->parameters.cw_params[i].cwmax,
2368 config->parameters.cw_params[i].aifsn);
2369 }
2370 }
2371
2372 // Set transceiver mode channel
2373 status = sl_wifi_transceiver_set_channel(interface, config->channel);
2374 if (status != SL_STATUS_OK) {
2375 SL_DEBUG_LOG("\r\nSet Channel Failed, Error Code : 0x%lX\r\n", status);
2376 return status;
2377 } else {
2378 SL_DEBUG_LOG("\r\nSet Channel(%d) Initialization success\r\n", config->channel.chan_info.channel);
2379 }
2380
2381 // Get DUT MAC address to use as Addr2/Transmitter Addresss
2382 status = sl_wifi_get_mac_address(interface, &config->dut_mac);
2383 if (status == SL_STATUS_OK) {
2384 SL_DEBUG_LOG("\r\nDevice MAC address: %x:%x:%x:%x:%x:%x\r\n",
2385 config->dut_mac.octet[0],
2386 config->dut_mac.octet[1],
2387 config->dut_mac.octet[2],
2388 config->dut_mac.octet[3],
2389 config->dut_mac.octet[4],
2390 config->dut_mac.octet[5]);
2391 } else {
2392 SL_DEBUG_LOG("\r\nFailed to get mac address: 0x%lX\r\n", status);
2393 return SL_STATUS_FAIL;
2394 }
2395
2396 return SL_STATUS_OK;
2397 }
2398
validate_datarate(sl_wifi_data_rate_t data_rate)2399 int32_t validate_datarate(sl_wifi_data_rate_t data_rate)
2400 {
2401 switch (data_rate) {
2402 case SL_WIFI_DATA_RATE_1:
2403 case SL_WIFI_DATA_RATE_2:
2404 case SL_WIFI_DATA_RATE_5_5:
2405 case SL_WIFI_DATA_RATE_11:
2406 case SL_WIFI_DATA_RATE_6:
2407 case SL_WIFI_DATA_RATE_9:
2408 case SL_WIFI_DATA_RATE_12:
2409 case SL_WIFI_DATA_RATE_18:
2410 case SL_WIFI_DATA_RATE_24:
2411 case SL_WIFI_DATA_RATE_36:
2412 case SL_WIFI_DATA_RATE_48:
2413 case SL_WIFI_DATA_RATE_54:
2414 return SL_STATUS_OK;
2415 default:
2416 return SL_STATUS_TRANSCEIVER_INVALID_DATA_RATE;
2417 }
2418 }
2419
sl_wifi_send_transceiver_data(sl_wifi_interface_t interface,sl_wifi_transceiver_tx_data_control_t * control,uint8_t * payload,uint16_t payload_len)2420 sl_status_t sl_wifi_send_transceiver_data(sl_wifi_interface_t interface,
2421 sl_wifi_transceiver_tx_data_control_t *control,
2422 uint8_t *payload,
2423 uint16_t payload_len)
2424 {
2425 sl_status_t status = SL_STATUS_OK;
2426
2427 if (!device_initialized) {
2428 return SL_STATUS_NOT_INITIALIZED;
2429 }
2430
2431 if (!sl_wifi_is_interface_up(interface)) {
2432 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
2433 }
2434
2435 if ((!payload_len) || (payload_len > MAX_PAYLOAD_LEN)) {
2436 return SL_STATUS_INVALID_PARAMETER;
2437 }
2438
2439 SL_VERIFY_POINTER_OR_RETURN(control, SL_STATUS_NULL_POINTER);
2440 SL_VERIFY_POINTER_OR_RETURN(payload, SL_STATUS_NULL_POINTER);
2441
2442 if (IS_FIXED_DATA_RATE(control->ctrl_flags)) {
2443 if (validate_datarate(control->rate)) {
2444 return SL_STATUS_TRANSCEIVER_INVALID_DATA_RATE;
2445 }
2446 }
2447
2448 status = sl_si91x_driver_send_transceiver_data(control, payload, payload_len, SL_SI91X_WAIT_FOR(1000));
2449
2450 return status;
2451 }
2452
sl_wifi_update_transceiver_peer_list(sl_wifi_interface_t interface,sl_wifi_transceiver_peer_update_t peer)2453 sl_status_t sl_wifi_update_transceiver_peer_list(sl_wifi_interface_t interface, sl_wifi_transceiver_peer_update_t peer)
2454 {
2455 sl_status_t status = SL_STATUS_OK;
2456
2457 if (!device_initialized) {
2458 return SL_STATUS_NOT_INITIALIZED;
2459 }
2460
2461 if (!sl_wifi_is_interface_up(interface)) {
2462 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
2463 }
2464
2465 if ((peer.flags & TRANSCEIVER_PEER_ADD_FLAG) && (peer.flags & TRANSCEIVER_PEER_AUTO_RATE_FLAG)
2466 && (!peer.peer_supported_rate_bitmap)) {
2467 return SL_STATUS_TRANSCEIVER_INVALID_DATA_RATE;
2468 }
2469
2470 if (IS_MAC_ZERO(peer.peer_mac_address)) {
2471 return SL_STATUS_TRANSCEIVER_INVALID_MAC_ADDRESS;
2472 }
2473 if (IS_BCAST_MCAST_MAC(peer.peer_mac_address[0])) {
2474 return SL_STATUS_TRANSCEIVER_INVALID_MAC_ADDRESS;
2475 }
2476
2477 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_TRANSCEIVER_PEER_LIST_UPDATE,
2478 SI91X_WLAN_CMD,
2479 &peer,
2480 sizeof(sl_wifi_transceiver_peer_update_t),
2481 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
2482 NULL,
2483 NULL);
2484 return status;
2485 }
2486
sl_wifi_set_transceiver_multicast_filter(sl_wifi_interface_t interface,sl_wifi_transceiver_mcast_filter_t mcast)2487 sl_status_t sl_wifi_set_transceiver_multicast_filter(sl_wifi_interface_t interface,
2488 sl_wifi_transceiver_mcast_filter_t mcast)
2489 {
2490 sl_status_t status = SL_STATUS_OK;
2491
2492 if (!device_initialized) {
2493 return SL_STATUS_NOT_INITIALIZED;
2494 }
2495
2496 if (!sl_wifi_is_interface_up(interface)) {
2497 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
2498 }
2499 if (mcast.flags & TRANSCEIVER_MCAST_FILTER_EN) {
2500 if ((!mcast.num_of_mcast_addr) || mcast.num_of_mcast_addr > TRANSCEIVER_MCAST_FILTER_ADDR_LIMIT) {
2501 return SL_STATUS_INVALID_PARAMETER;
2502 }
2503 for (uint8_t i = 0; i < mcast.num_of_mcast_addr; i++) {
2504 if (IS_MAC_ZERO(mcast.mac[i])) {
2505 return SL_STATUS_TRANSCEIVER_INVALID_MAC_ADDRESS;
2506 }
2507 }
2508 }
2509
2510 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_SET_TRANSCEIVER_MCAST_FILTER,
2511 SI91X_WLAN_CMD,
2512 &mcast,
2513 sizeof(sl_wifi_transceiver_mcast_filter_t),
2514 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
2515 NULL,
2516 NULL);
2517 return status;
2518 }
2519
sl_wifi_flush_transceiver_data(sl_wifi_interface_t interface)2520 sl_status_t sl_wifi_flush_transceiver_data(sl_wifi_interface_t interface)
2521 {
2522 sl_status_t status = SL_STATUS_OK;
2523
2524 if (!device_initialized) {
2525 return SL_STATUS_NOT_INITIALIZED;
2526 }
2527
2528 if (!sl_wifi_is_interface_up(interface)) {
2529 return SL_STATUS_WIFI_INTERFACE_NOT_UP;
2530 }
2531
2532 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_TRANSCEIVER_FLUSH_DATA_Q,
2533 SI91X_WLAN_CMD,
2534 NULL,
2535 0,
2536 SL_SI91X_WAIT_FOR_COMMAND_SUCCESS,
2537 NULL,
2538 NULL);
2539
2540 return status;
2541 }
2542
sl_wifi_configure_multicast_filter(sl_wifi_multicast_filter_info_t * multicast_filter_info)2543 sl_status_t sl_wifi_configure_multicast_filter(sl_wifi_multicast_filter_info_t *multicast_filter_info)
2544 {
2545 uint16_t multicast_bitmap = 0;
2546
2547 if (!device_initialized) {
2548 return SL_STATUS_NOT_INITIALIZED;
2549 }
2550 multicast_bitmap = (uint16_t)multicast_filter_info->command_type;
2551
2552 if ((multicast_filter_info->command_type == SL_WIFI_MULTICAST_MAC_ADD_BIT)
2553 || (multicast_filter_info->command_type == SL_WIFI_MULTICAST_MAC_CLEAR_BIT)) {
2554 multicast_bitmap |= (sli_multicast_mac_hash((uint8_t *)&(multicast_filter_info->mac_address)) << 8);
2555 }
2556
2557 sl_status_t status = SL_STATUS_OK;
2558
2559 status = sl_si91x_driver_send_command(RSI_WLAN_REQ_SET_MULTICAST_FILTER,
2560 SI91X_WLAN_CMD,
2561 &multicast_bitmap,
2562 sizeof(multicast_bitmap),
2563 SL_SI91X_WAIT_FOR(30100),
2564 NULL,
2565 NULL);
2566
2567 VERIFY_STATUS_AND_RETURN(status);
2568 return status;
2569 }
2570
sli_si91x_update_ap_client_info()2571 sl_status_t sli_si91x_update_ap_client_info()
2572 {
2573 return sl_wifi_get_ap_client_info(SL_WIFI_AP_INTERFACE, &sli_si91x_client_info);
2574 }
2575
sli_si91x_get_ap_client_ip_address_from_mac_address(const sl_mac_address_t mac_add)2576 sl_ip_address_t *sli_si91x_get_ap_client_ip_address_from_mac_address(const sl_mac_address_t mac_add)
2577 {
2578
2579 for (uint16_t station_info_index = 0; station_info_index < sli_si91x_client_info.client_count; station_info_index++) {
2580 sl_wifi_client_info_t *station_info = &sli_si91x_client_info.client_info[station_info_index];
2581 if (!memcmp((const uint8_t *)&mac_add, (uint8_t *)&station_info->mac_adddress, sizeof(sl_mac_address_t))) {
2582 return &station_info->ip_address;
2583 }
2584 }
2585 return NULL;
2586 }
2587