qcacmn: Hold a wakelock for management tx frames

Hold a timed wakelock whenever a management tx frame is sent, to
prevent issues around leaking descriptors or invalid access by firmware

Change-Id: If1a7ae69838791179b4a0365df3387146925509e
CRs-Fixed: 2033606
Tento commit je obsažen v:
Dustin Brown
2017-04-14 14:03:48 -07:00
odevzdal snandini
rodič 7726378826
revize 1f271a1bd4
3 změnil soubory, kde provedl 30 přidání a 2 odebrání

Zobrazit soubor

@@ -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",

Zobrazit soubor

@@ -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;
};

Zobrazit soubor

@@ -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);