Skip to content

Commit 5818738

Browse files
jerome-pouillerdanieldegrasse
authored andcommitted
drivers: wifi: siwx91x: Extract Power Save related functions
siwx91x_wifi.c starts to contains to much code. Let's simplify it by grouping all the power-save related functions in a separated file. Signed-off-by: Jérôme Pouiller <[email protected]>
1 parent 9a1ebee commit 5818738

File tree

4 files changed

+374
-338
lines changed

4 files changed

+374
-338
lines changed

drivers/wifi/siwx91x/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
# Copyright (c) 2024 Silicon Laboratories Inc.
33

44
if(CONFIG_WIFI_SILABS_SIWX91X)
5-
zephyr_library_sources(siwx91x_wifi.c siwx91x_wifi_ap.c siwx91x_wifi_scan.c)
5+
zephyr_library_sources(
6+
siwx91x_wifi.c
7+
siwx91x_wifi_ap.c
8+
siwx91x_wifi_scan.c
9+
siwx91x_wifi_ps.c)
610

711
if(CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD)
812
zephyr_library_sources(siwx91x_wifi_socket.c)

drivers/wifi/siwx91x/siwx91x_wifi.c

Lines changed: 3 additions & 337 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <nwp.h>
1313
#include "siwx91x_wifi.h"
1414
#include "siwx91x_wifi_ap.h"
15+
#include "siwx91x_wifi_ps.h"
1516
#include "siwx91x_wifi_scan.h"
1617
#include "siwx91x_wifi_socket.h"
1718

@@ -30,12 +31,6 @@ LOG_MODULE_REGISTER(siwx91x_wifi);
3031

3132
NET_BUF_POOL_FIXED_DEFINE(siwx91x_tx_pool, 1, _NET_ETH_MAX_FRAME_SIZE, 0, NULL);
3233

33-
enum {
34-
REQUEST_TWT = 0,
35-
SUGGEST_TWT = 1,
36-
DEMAND_TWT = 2,
37-
};
38-
3934
enum {
4035
STATE_IDLE = 0x00,
4136
/* Failover Roam */
@@ -191,203 +186,6 @@ static enum wifi_mfp_options siwx91x_set_sta_mfp_option(sl_wifi_security_t secur
191186
return WIFI_MFP_UNKNOWN;
192187
}
193188

194-
static int siwx91x_get_connected_ap_beacon_interval_ms(void)
195-
{
196-
sl_wifi_operational_statistics_t sl_stat;
197-
sl_wifi_interface_t interface;
198-
int status;
199-
200-
interface = sl_wifi_get_default_interface();
201-
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) != SL_WIFI_CLIENT_INTERFACE) {
202-
return 0;
203-
}
204-
205-
status = sl_wifi_get_operational_statistics(SL_WIFI_CLIENT_INTERFACE, &sl_stat);
206-
if (status) {
207-
return 0;
208-
}
209-
210-
return sys_get_le16(sl_stat.beacon_interval) * 1024 / 1000;
211-
}
212-
213-
static int siwx91x_apply_power_save(struct siwx91x_dev *sidev)
214-
{
215-
sl_wifi_performance_profile_t sl_ps_profile;
216-
sl_wifi_interface_t interface;
217-
int beacon_interval;
218-
int status;
219-
220-
interface = sl_wifi_get_default_interface();
221-
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) != SL_WIFI_CLIENT_INTERFACE) {
222-
LOG_ERR("Wi-Fi not in station mode");
223-
return -EINVAL;
224-
}
225-
226-
if (sidev->state == WIFI_STATE_INTERFACE_DISABLED) {
227-
LOG_ERR("Command given in invalid state");
228-
return -EINVAL;
229-
}
230-
231-
sl_wifi_get_performance_profile(&sl_ps_profile);
232-
233-
if (sidev->ps_params.enabled == WIFI_PS_DISABLED) {
234-
sl_ps_profile.profile = HIGH_PERFORMANCE;
235-
goto out;
236-
}
237-
if (sidev->ps_params.exit_strategy == WIFI_PS_EXIT_EVERY_TIM) {
238-
sl_ps_profile.profile = ASSOCIATED_POWER_SAVE_LOW_LATENCY;
239-
} else if (sidev->ps_params.exit_strategy == WIFI_PS_EXIT_CUSTOM_ALGO) {
240-
sl_ps_profile.profile = ASSOCIATED_POWER_SAVE;
241-
} else {
242-
/* Already sanitized by siwx91x_set_power_save() */
243-
return -EINVAL;
244-
}
245-
246-
sl_ps_profile.monitor_interval = sidev->ps_params.timeout_ms;
247-
248-
beacon_interval = siwx91x_get_connected_ap_beacon_interval_ms();
249-
/* 1000ms is arbitrary sane value */
250-
sl_ps_profile.listen_interval = MIN(beacon_interval * sidev->ps_params.listen_interval,
251-
1000);
252-
253-
if (sidev->ps_params.wakeup_mode == WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL &&
254-
!sidev->ps_params.listen_interval) {
255-
LOG_INF("Disabling listen interval based wakeup until connection establishes");
256-
}
257-
if (sidev->ps_params.wakeup_mode == WIFI_PS_WAKEUP_MODE_DTIM ||
258-
!sidev->ps_params.listen_interval) {
259-
sl_ps_profile.dtim_aligned_type = 1;
260-
} else if (sidev->ps_params.wakeup_mode == WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL) {
261-
sl_ps_profile.dtim_aligned_type = 0;
262-
} else {
263-
/* Already sanitized by siwx91x_set_power_save() */
264-
return -EINVAL;
265-
}
266-
267-
out:
268-
status = sl_wifi_set_performance_profile(&sl_ps_profile);
269-
return status ? -EIO : 0;
270-
}
271-
272-
static int siwx91x_set_power_save(const struct device *dev, struct wifi_ps_params *params)
273-
{
274-
struct siwx91x_dev *sidev = dev->data;
275-
int status;
276-
277-
__ASSERT(params, "params cannot be NULL");
278-
279-
switch (params->type) {
280-
case WIFI_PS_PARAM_STATE:
281-
sidev->ps_params.enabled = params->enabled;
282-
break;
283-
case WIFI_PS_PARAM_MODE:
284-
if (params->mode != WIFI_PS_MODE_LEGACY) {
285-
params->fail_reason = WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED;
286-
return -ENOTSUP;
287-
}
288-
break;
289-
case WIFI_PS_PARAM_LISTEN_INTERVAL:
290-
sidev->ps_params.listen_interval = params->listen_interval;
291-
break;
292-
case WIFI_PS_PARAM_WAKEUP_MODE:
293-
if (params->wakeup_mode != WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL &&
294-
params->wakeup_mode != WIFI_PS_WAKEUP_MODE_DTIM) {
295-
params->fail_reason = WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED;
296-
return -ENOTSUP;
297-
}
298-
sidev->ps_params.wakeup_mode = params->wakeup_mode;
299-
break;
300-
case WIFI_PS_PARAM_TIMEOUT:
301-
/* 1000ms is arbitrary sane value */
302-
if (params->timeout_ms < SLI_DEFAULT_MONITOR_INTERVAL ||
303-
params->timeout_ms > 1000) {
304-
params->fail_reason = WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL;
305-
return -EINVAL;
306-
}
307-
sidev->ps_params.timeout_ms = params->timeout_ms;
308-
break;
309-
case WIFI_PS_PARAM_EXIT_STRATEGY:
310-
if (params->exit_strategy != WIFI_PS_EXIT_EVERY_TIM &&
311-
params->exit_strategy != WIFI_PS_EXIT_CUSTOM_ALGO) {
312-
params->fail_reason = WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED;
313-
return -ENOTSUP;
314-
}
315-
sidev->ps_params.exit_strategy = params->exit_strategy;
316-
break;
317-
default:
318-
params->fail_reason = WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL;
319-
return -EINVAL;
320-
}
321-
status = siwx91x_apply_power_save(sidev);
322-
if (status) {
323-
params->fail_reason = WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL;
324-
return status;
325-
}
326-
return 0;
327-
}
328-
329-
static int siwx91x_get_power_save_config(const struct device *dev, struct wifi_ps_config *config)
330-
{
331-
sl_wifi_performance_profile_t sl_ps_profile;
332-
struct siwx91x_dev *sidev = dev->data;
333-
sl_wifi_interface_t interface;
334-
uint16_t beacon_interval;
335-
sl_status_t status;
336-
337-
__ASSERT(config, "config cannot be NULL");
338-
339-
interface = sl_wifi_get_default_interface();
340-
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) != SL_WIFI_CLIENT_INTERFACE) {
341-
LOG_ERR("Wi-Fi not in station mode");
342-
return -EINVAL;
343-
}
344-
345-
if (sidev->state == WIFI_STATE_INTERFACE_DISABLED) {
346-
LOG_ERR("Command given in invalid state");
347-
return -EINVAL;
348-
}
349-
350-
status = sl_wifi_get_performance_profile(&sl_ps_profile);
351-
if (status != SL_STATUS_OK) {
352-
LOG_ERR("Failed to get power save profile: 0x%x", status);
353-
return -EIO;
354-
}
355-
356-
switch (sl_ps_profile.profile) {
357-
case HIGH_PERFORMANCE:
358-
config->ps_params.enabled = WIFI_PS_DISABLED;
359-
break;
360-
case ASSOCIATED_POWER_SAVE_LOW_LATENCY:
361-
config->ps_params.enabled = WIFI_PS_ENABLED;
362-
config->ps_params.exit_strategy = WIFI_PS_EXIT_EVERY_TIM;
363-
break;
364-
case ASSOCIATED_POWER_SAVE:
365-
config->ps_params.enabled = WIFI_PS_ENABLED;
366-
config->ps_params.exit_strategy = WIFI_PS_EXIT_CUSTOM_ALGO;
367-
break;
368-
default:
369-
break;
370-
}
371-
372-
if (sl_ps_profile.dtim_aligned_type) {
373-
config->ps_params.wakeup_mode = WIFI_PS_WAKEUP_MODE_DTIM;
374-
} else {
375-
config->ps_params.wakeup_mode = WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL;
376-
377-
beacon_interval = siwx91x_get_connected_ap_beacon_interval_ms();
378-
if (beacon_interval > 0) {
379-
config->ps_params.listen_interval =
380-
sl_ps_profile.listen_interval / beacon_interval;
381-
}
382-
}
383-
384-
/* Device supports only legacy power-save mode */
385-
config->ps_params.mode = WIFI_PS_MODE_LEGACY;
386-
config->ps_params.timeout_ms = sl_ps_profile.monitor_interval;
387-
388-
return 0;
389-
}
390-
391189
static unsigned int siwx91x_on_join(sl_wifi_event_t event,
392190
char *result, uint32_t result_size, void *arg)
393191
{
@@ -929,138 +727,6 @@ static int siwx91x_dev_init(const struct device *dev)
929727
return 0;
930728
}
931729

932-
static int siwx91x_convert_z_sl_twt_req_type(enum wifi_twt_setup_cmd z_req_cmd)
933-
{
934-
switch (z_req_cmd) {
935-
case WIFI_TWT_SETUP_CMD_REQUEST:
936-
return REQUEST_TWT;
937-
case WIFI_TWT_SETUP_CMD_SUGGEST:
938-
return SUGGEST_TWT;
939-
case WIFI_TWT_SETUP_CMD_DEMAND:
940-
return DEMAND_TWT;
941-
default:
942-
return -EINVAL;
943-
}
944-
}
945-
946-
static int siwx91x_set_twt_setup(struct wifi_twt_params *params)
947-
{
948-
sl_status_t status;
949-
int twt_req_type = siwx91x_convert_z_sl_twt_req_type(params->setup_cmd);
950-
951-
sl_wifi_twt_request_t twt_req = {
952-
.twt_retry_interval = 5,
953-
.wake_duration_unit = 0,
954-
.wake_int_mantissa = params->setup.twt_mantissa,
955-
.un_announced_twt = !params->setup.announce,
956-
.wake_duration = params->setup.twt_wake_interval,
957-
.triggered_twt = params->setup.trigger,
958-
.wake_int_exp = params->setup.twt_exponent,
959-
.implicit_twt = 1,
960-
.twt_flow_id = params->flow_id,
961-
.twt_enable = 1,
962-
.req_type = twt_req_type,
963-
};
964-
965-
if (twt_req_type < 0) {
966-
params->fail_reason = WIFI_TWT_FAIL_CMD_EXEC_FAIL;
967-
return -EINVAL;
968-
}
969-
970-
if (!params->setup.twt_info_disable) {
971-
params->fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
972-
return -ENOTSUP;
973-
}
974-
975-
if (params->setup.responder) {
976-
params->fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
977-
return -ENOTSUP;
978-
}
979-
980-
/* implicit -> won't do renegotiation
981-
* explicit -> must do renegotiation for each session
982-
*/
983-
if (!params->setup.implicit) {
984-
/* explicit twt is not supported */
985-
params->fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
986-
return -ENOTSUP;
987-
}
988-
989-
if (params->setup.twt_wake_interval > 255 * 256) {
990-
twt_req.wake_duration_unit = 1;
991-
twt_req.wake_duration = params->setup.twt_wake_interval / 1024;
992-
} else {
993-
twt_req.wake_duration_unit = 0;
994-
twt_req.wake_duration = params->setup.twt_wake_interval / 256;
995-
}
996-
997-
status = sl_wifi_enable_target_wake_time(&twt_req);
998-
if (status != SL_STATUS_OK) {
999-
params->fail_reason = WIFI_TWT_FAIL_CMD_EXEC_FAIL;
1000-
params->resp_status = WIFI_TWT_RESP_NOT_RECEIVED;
1001-
return -EINVAL;
1002-
}
1003-
1004-
return 0;
1005-
}
1006-
1007-
static int siwx91x_set_twt_teardown(struct wifi_twt_params *params)
1008-
{
1009-
sl_status_t status;
1010-
sl_wifi_twt_request_t twt_req = { };
1011-
1012-
twt_req.twt_enable = 0;
1013-
1014-
if (params->teardown.teardown_all) {
1015-
twt_req.twt_flow_id = 0xFF;
1016-
} else {
1017-
twt_req.twt_flow_id = params->flow_id;
1018-
}
1019-
1020-
status = sl_wifi_disable_target_wake_time(&twt_req);
1021-
if (status != SL_STATUS_OK) {
1022-
params->fail_reason = WIFI_TWT_FAIL_CMD_EXEC_FAIL;
1023-
params->teardown_status = WIFI_TWT_TEARDOWN_FAILED;
1024-
return -EINVAL;
1025-
}
1026-
1027-
params->teardown_status = WIFI_TWT_TEARDOWN_SUCCESS;
1028-
1029-
return 0;
1030-
}
1031-
1032-
static int siwx91x_set_twt(const struct device *dev, struct wifi_twt_params *params)
1033-
{
1034-
sl_wifi_interface_t interface = sl_wifi_get_default_interface();
1035-
struct siwx91x_dev *sidev = dev->data;
1036-
1037-
__ASSERT(params, "params cannot be a NULL");
1038-
1039-
if (FIELD_GET(SIWX91X_INTERFACE_MASK, interface) != SL_WIFI_CLIENT_INTERFACE) {
1040-
params->fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
1041-
return -ENOTSUP;
1042-
}
1043-
1044-
if (sidev->state != WIFI_STATE_DISCONNECTED && sidev->state != WIFI_STATE_INACTIVE &&
1045-
sidev->state != WIFI_STATE_COMPLETED) {
1046-
LOG_ERR("Command given in invalid state");
1047-
return -EBUSY;
1048-
}
1049-
1050-
if (params->negotiation_type != WIFI_TWT_INDIVIDUAL) {
1051-
params->fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
1052-
return -ENOTSUP;
1053-
}
1054-
1055-
if (params->operation == WIFI_TWT_SETUP) {
1056-
return siwx91x_set_twt_setup(params);
1057-
} else if (params->operation == WIFI_TWT_TEARDOWN) {
1058-
return siwx91x_set_twt_teardown(params);
1059-
}
1060-
params->fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
1061-
return -ENOTSUP;
1062-
}
1063-
1064730
static const struct wifi_mgmt_ops siwx91x_mgmt = {
1065731
.scan = siwx91x_scan,
1066732
.connect = siwx91x_connect,
@@ -1072,12 +738,12 @@ static const struct wifi_mgmt_ops siwx91x_mgmt = {
1072738
.iface_status = siwx91x_status,
1073739
.mode = siwx91x_mode,
1074740
.set_twt = siwx91x_set_twt,
741+
.set_power_save = siwx91x_set_power_save,
742+
.get_power_save_config = siwx91x_get_power_save_config,
1075743
#if defined(CONFIG_NET_STATISTICS_WIFI)
1076744
.get_stats = siwx91x_stats,
1077745
#endif
1078746
.get_version = siwx91x_get_version,
1079-
.set_power_save = siwx91x_set_power_save,
1080-
.get_power_save_config = siwx91x_get_power_save_config,
1081747
};
1082748

1083749
static const struct net_wifi_mgmt_offload siwx91x_api = {

0 commit comments

Comments
 (0)