diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index 6b23f8401592..d2c2b5116552 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -38,6 +38,7 @@ #define mlme_legacy_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_MLME, params) #define mlme_legacy_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_MLME, params) +#define MLME_PEER_SET_KEY_WAKELOCK_TIMEOUT WAKELOCK_DURATION_RECOMMENDED /** * struct wlan_mlme_psoc_ext_obj -MLME ext psoc priv object * @cfg: cfg items @@ -85,6 +86,9 @@ struct sae_auth_retry { * @last_assoc_received_time: last assoc received time * @last_disassoc_deauth_received_time: last disassoc/deauth received time * @twt_ctx: TWT context + * @peer_set_key_wakelock: wakelock to protect peer set key op with firmware + * @peer_set_key_runtime_wakelock: runtime pm wakelock for set key + * @is_key_wakelock_set: flag to check if key wakelock is pending to release */ struct peer_mlme_priv_obj { uint8_t last_pn_valid; @@ -96,6 +100,9 @@ struct peer_mlme_priv_obj { #ifdef WLAN_SUPPORT_TWT struct twt_context twt_ctx; #endif + qdf_wake_lock_t peer_set_key_wakelock; + qdf_runtime_lock_t peer_set_key_runtime_wakelock; + bool is_key_wakelock_set; }; /** @@ -562,6 +569,32 @@ void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer, */ bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer); + +/** + * wlan_acquire_peer_key_wakelock -api to get key wakelock + * @pdev: pdev + * @mac_addr: peer mac addr + * + * This function acquires wakelock and prevent runtime pm during key + * installation + * + * Return: None + */ +void wlan_acquire_peer_key_wakelock(struct wlan_objmgr_pdev *pdev, + uint8_t *mac_addr); + +/** + * wlan_release_peer_key_wakelock -api to release key wakelock + * @pdev: pdev + * @mac_addr: peer mac addr + * + * This function releases wakelock and allow runtime pm after key + * installation + * + * Return: None + */ +void wlan_release_peer_key_wakelock(struct wlan_objmgr_pdev *pdev, + uint8_t *mac_addr); /** * mlme_set_discon_reason_n_from_ap() - set disconnect reason and from ap flag * @psoc: PSOC pointer diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index f2d633104945..3af2f88ad195 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -231,6 +231,10 @@ mlme_peer_object_created_notification(struct wlan_objmgr_peer *peer, qdf_mem_free(peer_priv); } + qdf_wake_lock_create(&peer_priv->peer_set_key_wakelock, "peer_set_key"); + qdf_runtime_lock_init(&peer_priv->peer_set_key_runtime_wakelock); + peer_priv->is_key_wakelock_set = false; + return status; } @@ -253,6 +257,10 @@ mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer, return QDF_STATUS_E_FAILURE; } + peer_priv->is_key_wakelock_set = false; + qdf_runtime_lock_deinit(&peer_priv->peer_set_key_runtime_wakelock); + qdf_wake_lock_destroy(&peer_priv->peer_set_key_wakelock); + status = wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_MLME, peer_priv); @@ -2839,6 +2847,88 @@ bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer) return peer_priv->is_pmf_enabled; } +void +wlan_acquire_peer_key_wakelock(struct wlan_objmgr_pdev *pdev, uint8_t *mac_addr) +{ + uint8_t pdev_id; + struct wlan_objmgr_peer *peer; + struct peer_mlme_priv_obj *peer_priv; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) + return; + + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, + WLAN_LEGACY_MAC_ID); + if (!peer) + return; + + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_MLME); + if (!peer_priv) { + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); + return; + } + + if (peer_priv->is_key_wakelock_set) { + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); + return; + } + + mlme_debug(QDF_MAC_ADDR_FMT ": Acquire set key wake lock for %d ms", + QDF_MAC_ADDR_REF(mac_addr), MLME_PEER_SET_KEY_WAKELOCK_TIMEOUT); + qdf_wake_lock_timeout_acquire(&peer_priv->peer_set_key_wakelock, + MLME_PEER_SET_KEY_WAKELOCK_TIMEOUT); + qdf_runtime_pm_prevent_suspend( + &peer_priv->peer_set_key_runtime_wakelock); + peer_priv->is_key_wakelock_set = true; + + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); +} + +void +wlan_release_peer_key_wakelock(struct wlan_objmgr_pdev *pdev, uint8_t *mac_addr) +{ + uint8_t pdev_id; + struct wlan_objmgr_peer *peer; + struct peer_mlme_priv_obj *peer_priv; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) + return; + + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, + WLAN_LEGACY_MAC_ID); + if (!peer) + return; + + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_MLME); + if (!peer_priv) { + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); + return; + } + + if (!peer_priv->is_key_wakelock_set) { + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); + return; + } + + peer_priv->is_key_wakelock_set = false; + mlme_debug(QDF_MAC_ADDR_FMT ": Release set key wake lock", + QDF_MAC_ADDR_REF(mac_addr)); + qdf_wake_lock_release(&peer_priv->peer_set_key_wakelock, + WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP); + qdf_runtime_pm_allow_suspend( + &peer_priv->peer_set_key_runtime_wakelock); + + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); +} + void mlme_set_discon_reason_n_from_ap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, bool from_ap, uint32_t reason_code) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 6543d708823b..e0d28e54f34f 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -6982,6 +6982,8 @@ int wlan_hdd_send_roam_auth_event(struct hdd_adapter *adapter, uint8_t *bssid, *((uint64_t *)roam_info_ptr->replay_ctr)); } else { + wlan_acquire_peer_key_wakelock(hdd_ctx->pdev, + roam_info_ptr->bssid.bytes); hdd_debug("No Auth Params TLV's"); if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, false)) { diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 6098ddc0f376..8821fa6995a0 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -689,8 +690,6 @@ struct wma_invalid_peer_params { * @ns_offload_req: cached ns offload request * @rcpi_req: rcpi request * @in_bmps: Whether bmps for this interface has been enabled - * @vdev_set_key_wakelock: wakelock to protect vdev set key op with firmware - * @vdev_set_key_runtime_wakelock: runtime pm wakelock for set key * @ch_freq: channel frequency * @roam_scan_stats_req: cached roam scan stats request * @wma_invalid_peer_params: structure storing invalid peer params @@ -738,8 +737,6 @@ struct wma_txrx_node { bool in_bmps; struct beacon_filter_param beacon_filter; bool beacon_filter_enabled; - qdf_wake_lock_t vdev_set_key_wakelock; - qdf_runtime_lock_t vdev_set_key_runtime_wakelock; struct roam_synch_frame_ind roam_synch_frame_ind; bool is_waiting_for_key; uint32_t ch_freq; diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 52a6a28a8795..68da62cca50f 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1644,6 +1644,7 @@ peer_detach: cdp_peer_delete(soc, vdev_id, peer_addr, bitmap); } + wlan_release_peer_key_wakelock(wma->pdev, peer_mac); wma_remove_objmgr_peer(wma, wma->interfaces[vdev_id].vdev, peer_mac); wma->interfaces[vdev_id].peer_count--; diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 128dfa9cb7da..03a51f01fbd4 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -5193,6 +5193,7 @@ static void wma_send_set_key_rsp(uint8_t vdev_id, bool pairwise, QDF_MAC_ADDR_SIZE); wma_send_msg_high_priority(wma, WMA_SET_STAKEY_RSP, key_info_uc, 0); + wlan_release_peer_key_wakelock(wma->pdev, crypto_key->macaddr); } else { key_info_mc = qdf_mem_malloc(sizeof(*key_info_mc)); if (!key_info_mc) @@ -5282,14 +5283,6 @@ void wma_update_set_key(uint8_t session_id, bool pairwise, if (iface) iface->is_waiting_for_key = false; - if (!pairwise && iface) { - /* Its GTK release the wake lock */ - wma_debug("Release set key wake lock"); - qdf_runtime_pm_allow_suspend( - &iface->vdev_set_key_runtime_wakelock); - wma_release_wakelock(&iface->vdev_set_key_wakelock); - } - wma_send_set_key_rsp(session_id, pairwise, key_index); } diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index bb73e6936aeb..9261497cbdf6 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2653,8 +2653,6 @@ static int wma_unified_phyerr_rx_event_handler(void *handle, void wma_vdev_init(struct wma_txrx_node *vdev) { - qdf_wake_lock_create(&vdev->vdev_set_key_wakelock, "vdev_set_key"); - qdf_runtime_lock_init(&vdev->vdev_set_key_runtime_wakelock); vdev->is_waiting_for_key = false; } @@ -2726,8 +2724,6 @@ void wma_vdev_deinit(struct wma_txrx_node *vdev) vdev->plink_status_req = NULL; } - qdf_runtime_lock_deinit(&vdev->vdev_set_key_runtime_wakelock); - qdf_wake_lock_destroy(&vdev->vdev_set_key_wakelock); vdev->is_waiting_for_key = false; } diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index e2403a053736..aa3b23e4087d 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -1446,14 +1446,11 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma, || params->encryptType == eSIR_ED_WPI #endif /* FEATURE_WLAN_WAPI */ ) { - if (!params->no_ptk_4_way) + if (!params->no_ptk_4_way) { cmd->need_ptk_4_way = 1; - wma_nofl_debug("Acquire set key wake lock for %d ms", - WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT); - wma_acquire_wakelock(&intr->vdev_set_key_wakelock, - WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT); - qdf_runtime_pm_prevent_suspend( - &intr->vdev_set_key_runtime_wakelock); + wlan_acquire_peer_key_wakelock(wma->pdev, + cmd->peer_mac); + } } if (params->wpa_rsn >> 1) cmd->need_gtk_2_way = 1;