diff --git a/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c b/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c index 78862f2bc4f7..edee454085c4 100644 --- a/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c +++ b/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -125,6 +125,11 @@ struct mgmt_txrx_desc_elem_t *wlan_mgmt_txrx_desc_get( struct mgmt_txrx_desc_elem_t, entry); mgmt_txrx_desc->in_use = true; + + /* acquire the wakelock when there are pending mgmt tx frames */ + qdf_wake_lock_timeout_acquire(&mgmt_txrx_ctx->wakelock_tx_cmp, + MGMT_TXRX_WAKELOCK_TIMEOUT_TX_CMP); + qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock); mgmt_txrx_info("retrieved mgmt desc: %p with desc id: %d", @@ -142,6 +147,13 @@ void wlan_mgmt_txrx_desc_put(struct mgmt_txrx_priv_context *mgmt_txrx_ctx, desc->in_use = false; qdf_list_insert_front(&mgmt_txrx_ctx->mgmt_desc_pool.free_list, &desc->entry); + + /* release the wakelock if there are no pending mgmt tx frames */ + if (mgmt_txrx_ctx->mgmt_desc_pool.free_list.count == + mgmt_txrx_ctx->mgmt_desc_pool.free_list.max_size) + qdf_wake_lock_release(&mgmt_txrx_ctx->wakelock_tx_cmp, + MGMT_TXRX_WAKELOCK_REASON_TX_CMP); + qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock); mgmt_txrx_info("put mgmt desc: %p with desc id: %d into freelist", diff --git a/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h b/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h index 1835619a8962..c6ae58c5a861 100644 --- a/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h +++ b/umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -36,6 +36,16 @@ #define IEEE80211_FC0_SUBTYPE_MASK 0xf0 #define IEEE80211_FC0_TYPE_MGT 0x00 +/** + * mgmt_wakelock_reason - reasons mgmt_txrx might hold a wakelock + * @MGMT_TXRX_WAKELOCK_REASON_TX_CMP - wait for mgmt_tx_complete event + */ +enum mgmt_txrx_wakelock_reason { + MGMT_TXRX_WAKELOCK_REASON_TX_CMP +}; + +/* timeout to wait for management_tx_complete event from firmware */ +#define MGMT_TXRX_WAKELOCK_TIMEOUT_TX_CMP 300 /* * generic definitions for IEEE 802.11 frames @@ -165,6 +175,7 @@ struct mgmt_txrx_stats_t { * @mgmt_rx_comp_cb: array of pointers of mgmt rx cbs * @mgmt_desc_pool: pointer to mgmt desc. pool * @mgmt_txrx_stats: pointer to mgmt txrx stats + * @wakelock_tx_cmp: mgmt tx complete wake lock */ struct mgmt_txrx_priv_context { struct wlan_objmgr_psoc *psoc; @@ -172,6 +183,7 @@ struct mgmt_txrx_priv_context { struct mgmt_desc_pool_t mgmt_desc_pool; struct mgmt_txrx_stats_t *mgmt_txrx_stats; qdf_spinlock_t mgmt_txrx_ctx_lock; + qdf_wake_lock_t wakelock_tx_cmp; }; diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c index 35733c901851..b5d9546c51a4 100644 --- a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c +++ b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c @@ -80,6 +80,8 @@ static QDF_STATUS wlan_mgmt_txrx_psoc_obj_create_notification( mgmt_txrx_ctx->mgmt_txrx_stats = mgmt_txrx_stats; qdf_spinlock_create(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock); + qdf_wake_lock_create(&mgmt_txrx_ctx->wakelock_tx_cmp, + "mgmt_txrx tx_cmp"); if (wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_UMAC_COMP_MGMT_TXRX, @@ -97,6 +99,7 @@ static QDF_STATUS wlan_mgmt_txrx_psoc_obj_create_notification( err_psoc_attach: qdf_spinlock_destroy(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock); + qdf_wake_lock_destroy(&mgmt_txrx_ctx->wakelock_tx_cmp); qdf_mem_free(mgmt_txrx_stats); err_mgmt_txrx_stats: wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_ctx); @@ -146,6 +149,7 @@ static QDF_STATUS wlan_mgmt_txrx_psoc_obj_destroy_notification( wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_ctx); qdf_mem_free(mgmt_txrx_ctx->mgmt_txrx_stats); qdf_spinlock_destroy(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock); + qdf_wake_lock_destroy(&mgmt_txrx_ctx->wakelock_tx_cmp); qdf_mem_free(mgmt_txrx_ctx); mgmt_txrx_info("mgmt txrx deletion successful, psoc: %p", psoc);