diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index 572c316763e4..58fd099cd859 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -881,7 +881,7 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, pm_ctx = policy_mgr_get_context(context); if (!pm_ctx) { policy_mgr_err("Invalid Context"); - return; + goto set_done_event; } policy_mgr_set_hw_mode_change_in_progress(context, @@ -889,14 +889,14 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, if (status != SET_HW_MODE_STATUS_OK) { policy_mgr_err("Set HW mode failed with status %d", status); - return; + goto set_done_event; } /* vdev mac map for NAN Discovery is expected in NAN Enable resp */ if (reason != POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY && !vdev_mac_map) { policy_mgr_err("vdev_mac_map is NULL"); - return; + goto set_done_event; } policy_mgr_debug("cfgd_hw_mode_index=%d", cfgd_hw_mode_index); @@ -910,7 +910,7 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, &hw_mode); if (ret != QDF_STATUS_SUCCESS) { policy_mgr_err("Get HW mode failed: %d", ret); - return; + goto set_done_event; } policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d, band_cap %d", @@ -940,12 +940,15 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, next_action, reason); else { policy_mgr_debug("No action needed right now"); - ret = policy_mgr_set_opportunistic_update(context); - if (!QDF_IS_STATUS_SUCCESS(ret)) - policy_mgr_err("ERROR: set opportunistic_update event failed"); + goto set_done_event; } return; + +set_done_event: + ret = policy_mgr_set_opportunistic_update(context); + if (!QDF_IS_STATUS_SUCCESS(ret)) + policy_mgr_err("ERROR: set opportunistic_update event failed"); } /** diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index 3bbd588e9b4c..34230d846cdb 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -27,10 +27,13 @@ #include "wlan_reg_services_api.h" #define DBS_OPPORTUNISTIC_TIME 5 + +#define POLICY_MGR_SER_CMD_TIMEOUT 4000 + #ifdef QCA_WIFI_3_0_EMU -#define CONNECTION_UPDATE_TIMEOUT 3000 +#define CONNECTION_UPDATE_TIMEOUT (POLICY_MGR_SER_CMD_TIMEOUT + 3000) #else -#define CONNECTION_UPDATE_TIMEOUT 1000 +#define CONNECTION_UPDATE_TIMEOUT (POLICY_MGR_SER_CMD_TIMEOUT + 2000) #endif #define PM_24_GHZ_CHANNEL_6 (6) diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index c317494f8c42..20bcfb4925f9 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -122,6 +122,11 @@ #define SME_CMD_ROAM_CMD_TIMEOUT (SIR_VDEV_START_REQUEST_TIMEOUT + 4000) #define SME_CMD_ADD_DEL_TS_TIMEOUT (4 * 1000) +/* + * POLICY_MGR_SER_CMD_TIMEOUT should be same as SME_CMD_POLICY_MGR_CMD_TIMEOUT + * if SME_CMD_POLICY_MGR_CMD_TIMEOUT is changed change + * POLICY_MGR_SER_CMD_TIMEOUT as well. + */ #define SME_CMD_POLICY_MGR_CMD_TIMEOUT (SIR_VDEV_PLCY_MGR_TIMEOUT + 2000) #define SME_POLICY_MGR_CMD_TIMEOUT (SME_CMD_POLICY_MGR_CMD_TIMEOUT + 1000) diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 519605585509..f640e0dc0f1d 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -575,6 +575,20 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, struct del_sta_self_params *pdel_sta_self_req_param, uint8_t generateRsp); +/** + * wma_release_vdev_and_peer_ref() - release vdev ref taken by interface txrx + * node and delete all the peers attached to this vdev + * @wma - wma handle + * @iface: wma interface txrx node + * + * This API release vdev ref taken by iface and all the peers attached to this + * vdev, this need to be called on recovery to flush vdev and peer. + * + * Return: void. + */ +void wma_release_vdev_and_peer_ref(tp_wma_handle wma, + struct wma_txrx_node *iface); + int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, uint32_t len); diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 0d5437958bc9..1b642db6c4dc 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -704,8 +704,7 @@ wma_cdp_vdev_detach(ol_txrx_soc_handle soc, /** * wma_release_vdev_ref() - Release vdev object reference count - * @wma_handle: wma handle - * @vdev_id: used to get wma interface txrx node + * @iface: wma interface txrx node * * Purpose of this function is to release vdev object reference count * from wma interface txrx node. @@ -713,12 +712,10 @@ wma_cdp_vdev_detach(ol_txrx_soc_handle soc, * Return: None */ static void -wma_release_vdev_ref(tp_wma_handle wma_handle, uint8_t vdev_id) +wma_release_vdev_ref(struct wma_txrx_node *iface) { - struct wma_txrx_node *iface; struct wlan_objmgr_vdev *vdev; - iface = &wma_handle->interfaces[vdev_id]; vdev = iface->vdev; iface->vdev = NULL; @@ -797,7 +794,7 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION); } WMA_LOGD("Call txrx detach with callback for vdev %d", vdev_id); - wma_release_vdev_ref(wma_handle, vdev_id); + wma_release_vdev_ref(iface); wma_cdp_vdev_detach(soc, wma_handle, vdev_id); /* @@ -811,7 +808,7 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, out: WMA_LOGE("Call txrx detach callback for vdev %d, generate_rsp %u", vdev_id, generate_rsp); - wma_release_vdev_ref(wma_handle, vdev_id); + wma_release_vdev_ref(iface); wma_cdp_vdev_detach(soc, wma_handle, vdev_id); wma_vdev_deinit(iface); @@ -827,35 +824,36 @@ out: /** * wma_force_objmgr_vdev_peer_cleanup() - Cleanup ObjMgr Vdev peers during SSR * @wma_handle: WMA handle - * @vdev_id: vdev ID + * @iface: wma interface txrx node * * Return: none */ static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma, - uint8_t vdev_id) + struct wma_txrx_node *iface) { - struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_peer *peer = NULL; struct wlan_objmgr_peer *peer_next = NULL; qdf_list_t *peer_list; - WMA_LOGE("%s: SSR: force cleanup peers in vdev(%d)", - __func__, vdev_id); - iface->vdev_active = false; - - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc, vdev_id, - WLAN_LEGACY_WMA_ID); - - if (!vdev) { - WMA_LOGE("Failed to get Objmgr Vdev"); + if (!iface->vdev) return; - } + + /* + * No need to take ref as if iface->vdev is valid then WMA already hold + * ref and this can be used diretly. ALso this API may get called after + * vdev deleted logically so taking ref for vdev will fail and peer + * wont be deleted for the vdev. + */ + vdev = iface->vdev; + + WMA_LOGI("%s: SSR: force cleanup peers in vdev(%d)", __func__, + wlan_vdev_get_id(vdev)); + iface->vdev_active = false; peer_list = &vdev->vdev_objmgr.wlan_peer_list; if (!peer_list) { WMA_LOGE("%s: peer_list is NULL", __func__); - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); return; } @@ -876,12 +874,22 @@ static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma, peer = peer_next; } - wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); - /* Force delete all the peers, set the wma interface peer_count to 0 */ iface->peer_count = 0; } +void wma_release_vdev_and_peer_ref(tp_wma_handle wma, + struct wma_txrx_node *iface) +{ + if (!iface) { + WMA_LOGE("iface is NULL"); + return; + } + + wma_force_objmgr_vdev_peer_cleanup(wma, iface); + wma_release_vdev_ref(iface); +} + static bool wma_vdev_uses_self_peer(uint32_t vdev_type, uint32_t vdev_subtype) { switch (vdev_type) { @@ -974,8 +982,7 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, * CDP Vdev. */ if (!cds_is_target_ready()) { - wma_force_objmgr_vdev_peer_cleanup(wma_handle, vdev_id); - wma_release_vdev_ref(wma_handle, vdev_id); + wma_release_vdev_and_peer_ref(wma_handle, iface); wma_cdp_vdev_detach(soc, wma_handle, vdev_id); goto send_rsp; } diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 61989ab3e1d9..c0bd8f05bacc 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -4660,6 +4660,9 @@ QDF_STATUS wma_wmi_service_close(void) wma_handle->wmi_handle = NULL; for (i = 0; i < wma_handle->max_bssid; i++) { + /* Release peer and vdev ref hold by wma if not already done */ + wma_release_vdev_and_peer_ref(wma_handle, + &wma_handle->interfaces[i]); wma_vdev_deinit(&wma_handle->interfaces[i]); }