Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: wifi: Add PS exit strategy runtime configuration #1458

Merged
merged 4 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified nrf_wifi/fw_bins/default/nrf70.bin
Binary file not shown.
Binary file modified nrf_wifi/fw_bins/radio_test/nrf70.bin
Binary file not shown.
Binary file modified nrf_wifi/fw_bins/scan_only/nrf70.bin
Binary file not shown.
16 changes: 16 additions & 0 deletions nrf_wifi/fw_if/umac_if/inc/default/fmac_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,22 @@ enum nrf_wifi_status nrf_wifi_fmac_set_ps_wakeup_mode(void *fmac_dev_ctx,
unsigned char if_idx,
bool ps_wakeup_mode);

/**
* @brief Configure power save exit strategy.
* @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device.
* @param if_idx Index of the interface on which power management is to be set.
* @param ps_exit_strategy PS exit strategy to be configured in RPU.
*
* This function is used to send a command to RPU
* to configure PS exit strategy in RPU.
*
* @return Command execution status
*/
enum nrf_wifi_status nrf_wifi_fmac_set_ps_exit_strategy(
void *fmac_dev_ctx,
unsigned char if_idx,
unsigned int ps_exit_strategy);

#ifdef CONFIG_NRF700X_RAW_DATA_TX
/**
* @brief Transmit a raw unaltered frame to the RPU.
Expand Down
2 changes: 2 additions & 0 deletions nrf_wifi/fw_if/umac_if/inc/fmac_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,6 @@ enum nrf_wifi_status umac_cmd_prog_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_
#endif /* CONFIG_NRF700X_RADIO_TEST */
int stat_type);

enum nrf_wifi_status umac_cmd_set_ps_exit_strategy(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
enum ps_exit_strategy ps_exit_strategy);
#endif /* __FMAC_CMD_H__ */
20 changes: 10 additions & 10 deletions nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_sys_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ enum op_band {
* @brief This enum defines keep alive state
*
*/
enum keep_alive_status {
enum nrf_wifi_keep_alive_status {
/** Keep alive feature disabled */
KEEP_ALIVE_DISABLED = 0,
/** Keep alive feature enabled */
Expand All @@ -843,13 +843,13 @@ enum keep_alive_status {
* @brief This enum specifies the type of frames used to retrieve buffered data
* from the AP in power save mode.
*/
enum data_retrieve_mechanism {
/** Retrieves data from the AP using a PS-Poll frame */
PS_POLL_FRAME,
/** Retrieves data from the AP using a QoS Null frame */
QOS_NULL_FRAME,
/** For future implementation. The RPU will decide which frame to use */
AUTOMATIC
enum ps_exit_strategy {
/** Uses an intelligent algo and decide whether to
* stay or exit power save mode to receive buffered frames.
*/
INT_PS = 0,
/** Exits power save mode for every TIM */
EVERY_TIM
};

#define TWT_EXTEND_SP_EDCA 0x1
Expand Down Expand Up @@ -897,9 +897,9 @@ struct nrf_wifi_cmd_sys_init {
*/
unsigned int discon_timeout;
/** RPU uses QoS null frame or PS-Poll frame to retrieve buffered frames
* from the AP in power save @ref data_retrieve_mechanism.
* from the AP in power save @ref ps_exit_strategy.
*/
unsigned char ps_data_retrieval_mech;
unsigned char ps_exit_strategy;
/** The RPU uses this value to configure watchdog timer */
unsigned int watchdog_timer_val;
/** The RPU uses this value to decide whether keep alive
Expand Down
18 changes: 17 additions & 1 deletion nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_umac_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ enum nrf_wifi_umac_commands {
/** Set listen interval @ref nrf_wifi_umac_cmd_set_listen_interval */
NRF_WIFI_UMAC_CMD_SET_LISTEN_INTERVAL,
/** Configure extended power save @ref nrf_wifi_umac_cmd_config_extended_ps */
NRF_WIFI_UMAC_CMD_CONFIG_EXTENDED_PS
NRF_WIFI_UMAC_CMD_CONFIG_EXTENDED_PS,
/** Command to specify power save exit strategy */
NRF_WIFI_UMAC_CMD_PS_EXIT_STRATEGY,
};

/**
Expand Down Expand Up @@ -2924,6 +2926,8 @@ struct nrf_wifi_umac_event_power_save_info {
unsigned int ps_timeout;
/** Listen interval value */
unsigned short listen_interval;
/** Power save exit strategy */
unsigned char ps_exit_strategy;
/** Number TWT flows */
unsigned char num_twt_flows;
/** TWT info of each flow @ref nrf_wifi_umac_config_twt_info */
Expand Down Expand Up @@ -3499,4 +3503,16 @@ struct nrf_wifi_umac_event_cmd_status {
unsigned int cmd_status;
} __NRF_WIFI_PKD;

/**
* @brief This structure defines the command used to configure the power save exit
* strategy for retrieving buffered data from the AP in power save mode.
*
*/
struct nrf_wifi_cmd_ps_exit_strategy {
/** Header @ref nrf_wifi_umac_hdr */
struct nrf_wifi_umac_hdr umac_hdr;
/** Power save exit strategy */
unsigned char ps_exit_strategy;
} __NRF_WIFI_PKD;

#endif /* __HOST_RPU_UMAC_IF_H */
8 changes: 4 additions & 4 deletions nrf_wifi/fw_if/umac_if/src/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,11 @@ enum nrf_wifi_status umac_cmd_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
umac_cmd_data->disable_beamforming = 1;
}

#if defined(CONFIG_NRF_WIFI_QOS_NULL_BASED_RETRIEVAL)
umac_cmd_data->ps_data_retrieval_mech = QOS_NULL_FRAME;
#if defined(CONFIG_NRF_WIFI_PS_INT_PS)
umac_cmd_data->ps_exit_strategy = INT_PS;
#else
umac_cmd_data->ps_data_retrieval_mech = PS_POLL_FRAME;
#endif /* CONFIG_NRF_WIFI_QOS_NULL_BASED_RETRIEVAL */
umac_cmd_data->ps_exit_strategy = EVERY_TIM;
#endif /* CONFIG_NRF_WIFI_PS_INT_PS */

status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
umac_cmd,
Expand Down
40 changes: 40 additions & 0 deletions nrf_wifi/fw_if/umac_if/src/default/fmac_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -3160,4 +3160,44 @@ enum nrf_wifi_status nrf_wifi_fmac_set_ps_wakeup_mode(void *dev_ctx,

return status;
}


enum nrf_wifi_status nrf_wifi_fmac_set_ps_exit_strategy(void *dev_ctx,
unsigned char if_idx,
unsigned int ps_exit_strategy)
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
struct nrf_wifi_cmd_ps_exit_strategy *set_ps_exit_strategy_cmd = NULL;
struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;

(void)if_idx;

fmac_dev_ctx = dev_ctx;

set_ps_exit_strategy_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv,
sizeof(*set_ps_exit_strategy_cmd));

if (!set_ps_exit_strategy_cmd) {
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: Unable to allocate memory\n", __func__);
goto out;
}

set_ps_exit_strategy_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_PS_EXIT_STRATEGY;
set_ps_exit_strategy_cmd->umac_hdr.ids.wdev_id = if_idx;
set_ps_exit_strategy_cmd->umac_hdr.ids.valid_fields |=
NRF_WIFI_INDEX_IDS_WDEV_ID_VALID;
set_ps_exit_strategy_cmd->ps_exit_strategy = ps_exit_strategy;

status = umac_cmd_cfg(fmac_dev_ctx,
set_ps_exit_strategy_cmd,
sizeof(*set_ps_exit_strategy_cmd));
out:
if (set_ps_exit_strategy_cmd) {
nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv,
set_ps_exit_strategy_cmd);
}

return status;
}
#endif /* CONFIG_NRF700X_STA_MODE */
1 change: 0 additions & 1 deletion nrf_wifi/hw_if/hal/inc/hal_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ struct nrf_wifi_hal_dev_ctx {
void *rpu_ps_timer;
void *rpu_ps_lock;
bool dbg_enable;
bool irq_ctx;
bool rpu_fw_booted;
#endif /* CONFIG_NRF_WIFI_LOW_POWER */
char *event_data;
Expand Down
35 changes: 3 additions & 32 deletions nrf_wifi/hw_if/hal/src/hal_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,9 @@ enum nrf_wifi_status hal_rpu_ps_wake(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
#endif /* CONFIG_NRF_WIFI_RPU_RECOVERY_PS_STATE_DEBUG */

out:
if (!hal_dev_ctx->irq_ctx) {
nrf_wifi_osal_timer_schedule(hal_dev_ctx->hpriv->opriv,
hal_dev_ctx->rpu_ps_timer,
CONFIG_NRF700X_RPU_PS_IDLE_TIMEOUT_MS);
}
nrf_wifi_osal_timer_schedule(hal_dev_ctx->hpriv->opriv,
hal_dev_ctx->rpu_ps_timer,
CONFIG_NRF700X_RPU_PS_IDLE_TIMEOUT_MS);
return status;
}

Expand Down Expand Up @@ -506,13 +504,6 @@ static void hal_rpu_ps_deinit(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
hal_dev_ctx->rpu_ps_lock);
}


static void hal_rpu_ps_set_state(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
enum RPU_PS_STATE ps_state)
{
hal_dev_ctx->rpu_ps_state = ps_state;
}

enum nrf_wifi_status nrf_wifi_hal_get_rpu_ps_state(
struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
int *rpu_ps_ctrl_state)
Expand Down Expand Up @@ -1566,9 +1557,6 @@ enum nrf_wifi_status nrf_wifi_hal_irq_handler(void *data)
struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL;
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
unsigned long flags = 0;
#ifdef CONFIG_NRF_WIFI_LOW_POWER
enum RPU_PS_STATE ps_state = RPU_PS_STATE_ASLEEP;
#endif /* CONFIG_NRF_WIFI_LOW_POWER */
bool do_rpu_recovery = false;

hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)data;
Expand All @@ -1588,25 +1576,8 @@ enum nrf_wifi_status nrf_wifi_hal_irq_handler(void *data)
goto unlock;
}

#ifdef CONFIG_NRF_WIFI_LOW_POWER
ps_state = hal_dev_ctx->rpu_ps_state;
hal_rpu_ps_set_state(hal_dev_ctx,
RPU_PS_STATE_AWAKE);
#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG
hal_dev_ctx->irq_ctx = true;
#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */
#endif /* CONFIG_NRF_WIFI_LOW_POWER */

status = hal_rpu_irq_process(hal_dev_ctx, &do_rpu_recovery);

#ifdef CONFIG_NRF_WIFI_LOW_POWER
hal_rpu_ps_set_state(hal_dev_ctx,
ps_state);
#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG
hal_dev_ctx->irq_ctx = false;
#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */
#endif /* CONFIG_NRF_WIFI_LOW_POWER */

if (status != NRF_WIFI_STATUS_SUCCESS) {
goto unlock;
}
Expand Down
32 changes: 26 additions & 6 deletions nrf_wifi/hw_if/hal/src/hal_interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,35 @@ static bool hal_rpu_irq_wdog_chk(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
unsigned int val = 0;
bool ret = false;
unsigned int i, max_read_retries = 10;

status = hal_rpu_reg_read(hal_dev_ctx,
&val,
RPU_REG_MIPS_MCU_UCCP_INT_STATUS);
for (i = 0; i < max_read_retries; i++) {
status = hal_rpu_reg_read(hal_dev_ctx,
&val,
RPU_REG_MIPS_MCU_UCCP_INT_STATUS);

if (status != NRF_WIFI_STATUS_SUCCESS) {
nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv,
"%s: Reading from interrupt status register failed\n",
__func__);
goto out;
}

if (val != 0xAAAAAAAA) {
break;
}

if (status != NRF_WIFI_STATUS_SUCCESS) {
nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv,
"%s: Reading from interrupt status register failed",
__func__);
"%s: Reading from interrupt status register failed 0x%x\n",
__func__,
val);
}

if (i == max_read_retries) {
nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv,
"%s: Reading from interrupt status register failed 0x%x\n",
__func__,
val);
goto out;
}

Expand Down
Loading