mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 00:24:41 -04:00
qcacld-3.0: Flush pending powersave timers during suspend
Currently, auto powersave timers are deferrable. This means any pending auto powersave timers will not fire while the device is supended, which can have a negative impact on wlan power usage. Instead, flush any pending auto powersave timers during the suspend process, to ensure powersave is enabled while the device is suspended. Change-Id: I5911ee30eaf770909b728af73958ba1bbaa8457f CRs-Fixed: 2080812
This commit is contained in:
parent
6b92adff7d
commit
84411b0e45
5 changed files with 90 additions and 26 deletions
|
|
@ -2242,7 +2242,7 @@ static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
|
|||
sme_ps_enable_auto_ps_timer(
|
||||
WLAN_HDD_GET_HAL_CTX(adapter),
|
||||
adapter->sessionId,
|
||||
timeout, false);
|
||||
timeout);
|
||||
}
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
|
|
|
|||
|
|
@ -1452,7 +1452,6 @@ int wlan_hdd_set_powersave(hdd_adapter_t *adapter,
|
|||
{
|
||||
tHalHandle hal;
|
||||
hdd_context_t *hdd_ctx;
|
||||
bool force_trigger = false;
|
||||
|
||||
if (NULL == adapter) {
|
||||
hdd_err("Adapter NULL");
|
||||
|
|
@ -1468,13 +1467,18 @@ int wlan_hdd_set_powersave(hdd_adapter_t *adapter,
|
|||
hdd_debug("Allow power save: %d", allow_power_save);
|
||||
hal = WLAN_HDD_GET_HAL_CTX(adapter);
|
||||
|
||||
if ((QDF_STA_MODE == adapter->device_mode) &&
|
||||
/*
|
||||
* This is a workaround for defective AP's that send a disassoc
|
||||
* immediately after WPS connection completes. Defer powersave by a
|
||||
* small amount if the affected AP is detected.
|
||||
*/
|
||||
if (allow_power_save &&
|
||||
adapter->device_mode == QDF_STA_MODE &&
|
||||
!adapter->sessionCtx.station.ap_supports_immediate_power_save) {
|
||||
/* override user's requested flag */
|
||||
force_trigger = allow_power_save;
|
||||
allow_power_save = false;
|
||||
timeout = AUTO_PS_ENTRY_USER_TIMER_DEFAULT_VALUE;
|
||||
hdd_debug("Defer power-save for few seconds...");
|
||||
timeout = AUTO_PS_DEFER_TIMEOUT_MS;
|
||||
hdd_debug("Defer power-save due to AP spec non-conformance");
|
||||
}
|
||||
|
||||
if (allow_power_save) {
|
||||
|
|
@ -1509,7 +1513,7 @@ int wlan_hdd_set_powersave(hdd_adapter_t *adapter,
|
|||
adapter->sessionId);
|
||||
sme_ps_enable_disable(hal, adapter->sessionId, SME_PS_DISABLE);
|
||||
sme_ps_enable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX(adapter),
|
||||
adapter->sessionId, timeout, force_trigger);
|
||||
adapter->sessionId, timeout);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -1796,6 +1800,17 @@ next_adapter:
|
|||
pAdapterNode = pNext;
|
||||
}
|
||||
|
||||
/* flush any pending powersave timers */
|
||||
status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
|
||||
while (pAdapterNode && QDF_IS_STATUS_SUCCESS(status)) {
|
||||
pAdapter = pAdapterNode->pAdapter;
|
||||
|
||||
sme_ps_timer_flush_sync(pHddCtx->hHal, pAdapter->sessionId);
|
||||
|
||||
status = hdd_get_next_adapter(pHddCtx, pAdapterNode,
|
||||
&pAdapterNode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Suspend IPA early before proceeding to suspend other entities like
|
||||
* firmware to avoid any race conditions.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
|
|
@ -35,18 +35,14 @@
|
|||
#include "sir_api.h"
|
||||
|
||||
#define MAX_SME_SESSIONS 5
|
||||
/* Auto Ps Entry Timer Default value - 1000 ms */
|
||||
#define AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE 1000
|
||||
|
||||
/* Auto Deferred Ps Entry Timer value - 20000 ms */
|
||||
#define AUTO_DEFERRED_PS_ENTRY_TIMER_DEFAULT_VALUE 20000
|
||||
|
||||
/*
|
||||
* Auto Ps Entry User default timeout value, used instead of negative timeouts
|
||||
* from user space - 5000ms
|
||||
*/
|
||||
#define AUTO_PS_ENTRY_USER_TIMER_DEFAULT_VALUE 5000
|
||||
|
||||
#define AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE 1000
|
||||
#define AUTO_PS_DEFER_TIMEOUT_MS 1500
|
||||
|
||||
/**
|
||||
* enum ps_state - State of the power save
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
QDF_STATUS sme_ps_enable_disable(tHalHandle hal_ctx, uint32_t session_id,
|
||||
enum sme_ps_cmd command);
|
||||
|
||||
QDF_STATUS sme_ps_timer_flush_sync(tHalHandle hal, uint8_t session_id);
|
||||
|
||||
QDF_STATUS sme_ps_uapsd_enable(tHalHandle hal_ctx, uint32_t session_id);
|
||||
|
||||
QDF_STATUS sme_ps_uapsd_disable(tHalHandle hal_ctx, uint32_t session_id);
|
||||
|
|
@ -75,12 +77,11 @@ tSirRetStatus sme_post_pe_message(tpAniSirGlobal mac_ctx,
|
|||
* @hal_ctx: HAL context
|
||||
* @session_id: adapter session Id
|
||||
* @timeout: timeout period in ms
|
||||
* @force_trigger: forcing power-save timer to trigger
|
||||
*
|
||||
* Returns: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS sme_ps_enable_auto_ps_timer(tHalHandle hal_ctx,
|
||||
uint32_t sessionId, uint32_t timeout, bool force_trigger);
|
||||
uint32_t sessionId, uint32_t timeout);
|
||||
QDF_STATUS sme_ps_disable_auto_ps_timer(tHalHandle hal_ctx,
|
||||
uint32_t sessionId);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@
|
|||
#include "sme_trace.h"
|
||||
#include "qdf_mem.h"
|
||||
#include "qdf_types.h"
|
||||
#include "wma_types.h"
|
||||
#include "wma.h"
|
||||
#include "wma_internal.h"
|
||||
#include "wmm_apsd.h"
|
||||
#include "cfg_api.h"
|
||||
#include "csr_inside_api.h"
|
||||
|
|
@ -528,6 +529,56 @@ QDF_STATUS sme_ps_enable_disable(tHalHandle hal_ctx, uint32_t session_id,
|
|||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS sme_ps_timer_flush_sync(tHalHandle hal, uint8_t session_id)
|
||||
{
|
||||
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
|
||||
struct ps_params *ps_parm;
|
||||
enum ps_state ps_state;
|
||||
QDF_TIMER_STATE tstate;
|
||||
struct sEnablePsParams *req;
|
||||
t_wma_handle *wma;
|
||||
|
||||
ps_parm = &mac_ctx->sme.ps_global_info.ps_params[session_id];
|
||||
tstate = qdf_mc_timer_get_current_state(&ps_parm->auto_ps_enable_timer);
|
||||
if (tstate != QDF_TIMER_STATE_RUNNING)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
sme_debug("flushing powersave enable for vdev %u", session_id);
|
||||
|
||||
wma = cds_get_context(QDF_MODULE_ID_WMA);
|
||||
if (!wma) {
|
||||
sme_err("wma is null");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
qdf_mc_timer_stop(&ps_parm->auto_ps_enable_timer);
|
||||
|
||||
req = qdf_mem_malloc(sizeof(*req));
|
||||
if (!req) {
|
||||
sme_err("out of memory");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
if (ps_parm->uapsd_per_ac_bit_mask) {
|
||||
req->psSetting = eSIR_ADDON_ENABLE_UAPSD;
|
||||
sme_ps_fill_uapsd_req_params(mac_ctx, &req->uapsdParams,
|
||||
session_id, &ps_state);
|
||||
ps_state = UAPSD_MODE;
|
||||
req->uapsdParams.enable_ps = true;
|
||||
} else {
|
||||
req->psSetting = eSIR_ADDON_NOTHING;
|
||||
ps_state = LEGACY_POWER_SAVE_MODE;
|
||||
}
|
||||
req->sessionid = session_id;
|
||||
|
||||
wma_enable_sta_ps_mode(wma, req);
|
||||
qdf_mem_free(req);
|
||||
|
||||
ps_parm->ps_state = ps_state;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* sme_ps_uapsd_enable(): function to enable UAPSD.
|
||||
* @hal_ctx: global hal_handle
|
||||
|
|
@ -821,16 +872,15 @@ tSirRetStatus sme_post_pe_message(tpAniSirGlobal mac_ctx,
|
|||
}
|
||||
|
||||
QDF_STATUS sme_ps_enable_auto_ps_timer(tHalHandle hal_ctx,
|
||||
uint32_t session_id, uint32_t timeout, bool force_trigger)
|
||||
uint32_t session_id, uint32_t timeout)
|
||||
{
|
||||
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
|
||||
struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
|
||||
struct ps_params *ps_param = &ps_global_info->ps_params[session_id];
|
||||
QDF_STATUS qdf_status;
|
||||
|
||||
if (!ps_global_info->auto_bmps_timer_val && !force_trigger) {
|
||||
sme_debug("auto_ps_timer is disabled in INI, force_trigger-%d",
|
||||
force_trigger);
|
||||
if (!timeout) {
|
||||
sme_debug("auto_ps_timer called with timeout 0; ignore");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -908,19 +958,21 @@ QDF_STATUS sme_ps_open_per_session(tHalHandle hal_ctx, uint32_t session_id)
|
|||
|
||||
void sme_auto_ps_entry_timer_expired(void *data)
|
||||
{
|
||||
struct ps_params *ps_params = (struct ps_params *)data;
|
||||
struct ps_params *ps_params = (struct ps_params *)data;
|
||||
tpAniSirGlobal mac_ctx = (tpAniSirGlobal)ps_params->mac_ctx;
|
||||
uint32_t session_id = ps_params->session_id;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
QDF_STATUS status;
|
||||
|
||||
sme_debug("auto_ps_timer expired, enabling powersave");
|
||||
|
||||
status = sme_enable_sta_ps_check(mac_ctx, session_id);
|
||||
if (QDF_STATUS_SUCCESS == status)
|
||||
sme_ps_enable_disable((tHalHandle)mac_ctx, session_id,
|
||||
SME_PS_ENABLE);
|
||||
else {
|
||||
status =
|
||||
qdf_mc_timer_start(&ps_params->auto_ps_enable_timer,
|
||||
AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE);
|
||||
sme_debug("failed to enable powersave, restarting timer");
|
||||
status = qdf_mc_timer_start(&ps_params->auto_ps_enable_timer,
|
||||
AUTO_PS_ENTRY_TIMER_DEFAULT_VALUE);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)
|
||||
&& (QDF_STATUS_E_ALREADY != status))
|
||||
sme_err("Cannot start traffic timer");
|
||||
|
|
|
|||
Loading…
Reference in a new issue