diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 1ed5f27ff179..bbe716bc617d 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -1186,6 +1186,11 @@ QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc) } gp_cds_context->mac_context = NULL; + /* + * Call this before cdp soc detatch as it used the cdp soc to free the + * cdp vdev if any. + */ + wma_release_pending_vdev_refs(); cdp_soc_detach(gp_cds_context->dp_soc); gp_cds_context->dp_soc = NULL; diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index f81769fcd588..f7f19d7b8e2f 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1897,8 +1897,7 @@ void wma_vdev_update_pause_bitmap(uint8_t vdev_id, uint16_t value) } if (!wlan_vdev_get_dp_handle(iface->vdev)) { - WMA_LOGE("%s: Failed to get iface handle: NULL", - __func__); + WMA_LOGE("%s: Failed to get dp handle", __func__); return; } @@ -1930,8 +1929,7 @@ uint16_t wma_vdev_get_pause_bitmap(uint8_t vdev_id) } if (!wlan_vdev_get_dp_handle(iface->vdev)) { - WMA_LOGE("%s: Failed to get iface handle: NULL", - __func__); + WMA_LOGE("%s: Failed to get dp handle", __func__); return 0; } @@ -1992,8 +1990,7 @@ static inline bool wma_vdev_is_device_in_low_pwr_mode(uint8_t vdev_id) } if (!wlan_vdev_get_dp_handle(iface->vdev)) { - WMA_LOGE("%s: Failed to get iface handle:NULL", - __func__); + WMA_LOGE("%s: Failed to get dp handle", __func__); return 0; } @@ -2116,8 +2113,7 @@ void wma_vdev_set_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) } if (!wlan_vdev_get_dp_handle(iface->vdev)) { - WMA_LOGE("%s: Failed to get iface handle: NULL", - __func__); + WMA_LOGE("%s: Failed to get dp handle", __func__); return; } @@ -2150,8 +2146,7 @@ void wma_vdev_clear_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) } if (!wlan_vdev_get_dp_handle(iface->vdev)) { - WMA_LOGE("%s: Failed to get iface handle: NULL", - __func__); + WMA_LOGE("%s: Failed to get dp handle", __func__); return; } @@ -2651,4 +2646,16 @@ QDF_STATUS wma_post_vdev_start_setup(uint8_t vdev_id); QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id, struct bss_params *add_bss); +/** + * wma_release_pending_vdev_refs() - release vdev ref taken by interface txrx + * node and delete all the peers attached to this vdev. + * + * This API loop and release vdev ref taken by all iface and all the peers + * attached to the vdev, this need to be called on recovery to flush vdev + * and peer. + * + * Return: void. + */ +void wma_release_pending_vdev_refs(void); + #endif diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index c1315bc80bfd..247df037c26b 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -708,20 +708,6 @@ struct cdp_vdev *wma_find_vdev_by_bssid(tp_wma_handle wma, uint8_t *bssid, QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, struct del_vdev_params *pdel_vdev_req_param); -/** - * 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); - QDF_STATUS wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id, uint32_t param_id, uint32_t param_value); diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index edb725ffdafe..e6b159b3d709 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -3034,8 +3034,7 @@ void wma_tx_abort(uint8_t vdev_id) } handle = wlan_vdev_get_dp_handle(iface->vdev); if (!handle) { - WMA_LOGE("%s: Failed to get iface handle: %pK", - __func__, handle); + WMA_LOGE("%s: Failed to get dp handle", __func__); return; } bssid = wma_get_vdev_bssid(iface->vdev); diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 6faaa00fdc51..938ca0b940b2 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -560,6 +560,26 @@ error: return qdf_status; } +static void +wma_cdp_vdev_detach(ol_txrx_soc_handle soc, tp_wma_handle wma_handle, + uint8_t vdev_id) +{ + struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; + struct wlan_objmgr_vdev *vdev = iface->vdev; + struct cdp_vdev *cdp_vdev; + + if (!vdev) { + WMA_LOGE(FL("vdev is NULL")); + return; + } + + cdp_vdev = wlan_vdev_get_dp_handle(vdev); + if (soc && cdp_vdev) { + wlan_vdev_set_dp_handle(vdev, NULL); + cdp_vdev_detach(soc, cdp_vdev, NULL, NULL); + } +} + /** * wma_release_vdev_ref() - Release vdev object reference count * @iface: wma interface txrx node @@ -620,20 +640,21 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, if (!soc) { WMA_LOGE("%s:SOC context is NULL", __func__); - goto out; + goto rel_ref; } vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev); if (!vdev_mlme) { wma_err("Failed to get vdev mlme obj for vdev id %d", del_vdev_req_param->vdev_id); - goto out; + goto rel_ref; } if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) wma_handle_monitor_mode_vdev_detach(wma_handle, vdev_id); iface->del_staself_req = del_vdev_req_param; + wma_cdp_vdev_detach(soc, wma_handle, vdev_id); wma_release_vdev_ref(iface); status = vdev_mgr_delete_send(vdev_mlme); @@ -644,9 +665,10 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, return status; -out: - wlan_vdev_set_dp_handle(iface->vdev, NULL); +rel_ref: + wma_cdp_vdev_detach(soc, wma_handle, vdev_id); wma_release_vdev_ref(iface); +out: wma_vdev_deinit(iface); qdf_mem_zero(iface, sizeof(*iface)); wma_vdev_init(iface); @@ -670,6 +692,7 @@ static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma, struct wlan_objmgr_peer *peer = NULL; struct wlan_objmgr_peer *peer_next = NULL; qdf_list_t *peer_list; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); if (!iface->vdev) return; @@ -682,6 +705,8 @@ static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma, */ vdev = iface->vdev; + wma_cdp_vdev_detach(soc, wma, wlan_vdev_get_id(vdev)); + WMA_LOGI("%s: SSR: force cleanup peers in vdev(%d)", __func__, wlan_vdev_get_id(vdev)); iface->vdev_active = false; @@ -713,8 +738,9 @@ static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma, iface->peer_count = 0; } -void wma_release_vdev_and_peer_ref(tp_wma_handle wma, - struct wma_txrx_node *iface) +static void +wma_release_vdev_and_peer_ref(tp_wma_handle wma, + struct wma_txrx_node *iface) { if (!iface) { WMA_LOGE("iface is NULL"); @@ -725,6 +751,22 @@ void wma_release_vdev_and_peer_ref(tp_wma_handle wma, wma_release_vdev_ref(iface); } +void wma_release_pending_vdev_refs(void) +{ + int i; + tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); + + /* validate the wma_handle */ + if (!wma) { + WMA_LOGE("%s: Invalid wma handle", __func__); + return; + } + + for (i = 0; i < wma->max_bssid; i++) + /* Release peer and vdev ref hold by wma if not already done */ + wma_release_vdev_and_peer_ref(wma, &wma->interfaces[i]); +} + static bool wma_vdev_uses_self_peer(uint32_t vdev_type, uint32_t vdev_subtype) { switch (vdev_type) { @@ -799,8 +841,8 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, } if (!wlan_vdev_get_dp_handle(iface->vdev)) { - WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed", - vdev_id); + WMA_LOGE("%s: Failed to get dp handle for vdev id %d", + __func__, vdev_id); goto send_rsp; } @@ -2102,7 +2144,7 @@ void wma_send_del_bss_response(tp_wma_handle wma, struct del_bss_resp *resp) } handle = wlan_vdev_get_dp_handle(iface->vdev); if (!handle) { - WMA_LOGE("%s vdev id %d is already deleted", + WMA_LOGE("%s: Failed to get dp handle for vdev id %d", __func__, vdev_id); if (resp) qdf_mem_free(resp); @@ -2324,7 +2366,7 @@ __wma_handle_vdev_stop_rsp(struct vdev_stop_response *resp_event) uint8_t type; if (!wlan_vdev_get_dp_handle(iface->vdev)) { - WMA_LOGE("%s vdev id %d is already deleted", + WMA_LOGE("%s: Failed to get dp handle for vdev id %d", __func__, resp_event->vdev_id); status = -EINVAL; goto free_params; @@ -2445,17 +2487,22 @@ QDF_STATUS wma_post_vdev_create_setup(struct wlan_objmgr_vdev *vdev) QDF_STATUS_SUCCESS) return QDF_STATUS_E_FAILURE; + vdev_id = wlan_vdev_get_id(vdev); + wma_handle->interfaces[vdev_id].vdev = vdev; + wma_handle->interfaces[vdev_id].vdev_active = true; + txrx_vdev_handle = wlan_vdev_get_dp_handle(vdev); + if (!txrx_vdev_handle) { + WMA_LOGE("%s: Failed to get dp handle for vdev id %d", + __func__, vdev_id); + goto end; + } + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); if (!vdev_mlme) { WMA_LOGE("%s: Failed to get vdev mlme obj!", __func__); - return QDF_STATUS_E_FAILURE; + goto end; } - vdev_id = wlan_vdev_get_id(vdev); - txrx_vdev_handle = wlan_vdev_get_dp_handle(vdev); - wma_handle->interfaces[vdev_id].vdev = vdev; - - wma_handle->interfaces[vdev_id].vdev_active = true; wma_vdev_update_pause_bitmap(vdev_id, 0); wma_handle->interfaces[vdev_id].type = @@ -2707,9 +2754,10 @@ QDF_STATUS wma_post_vdev_create_setup(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_SUCCESS; end: + wma_cdp_vdev_detach(soc, wma_handle, vdev_id); + wma_handle->interfaces[vdev_id].vdev = NULL; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); wma_handle->interfaces[vdev_id].vdev_active = false; - txrx_vdev_handle = NULL; return QDF_STATUS_E_FAILURE; } @@ -3385,7 +3433,7 @@ QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id, vdev = wlan_vdev_get_dp_handle(iface->vdev); if (!vdev) { - wma_err("Failed to get vdev handle: %d", vdev_id); + wma_err("Failed to get dp handle fro vdev id %d", vdev_id); return QDF_STATUS_E_FAILURE; } diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 04a5d10951a2..96670e814653 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -4600,12 +4600,8 @@ QDF_STATUS wma_wmi_service_close(void) wmi_unified_detach(wma_handle->wmi_handle); 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]); + for (i = 0; i < wma_handle->max_bssid; i++) wma_vdev_deinit(&wma_handle->interfaces[i]); - } qdf_mem_free(wma_handle->interfaces); diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index c10047368c23..6535b09895ca 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -554,7 +554,8 @@ int wma_unified_bcntx_status_event_handler(void *handle, dp_handle = wlan_vdev_get_dp_handle (wma->interfaces[resp_event->vdev_id].vdev); if (!dp_handle) { - WMA_LOGE("%s: The session does not exist", __func__); + WMA_LOGE("%s: Failed to get dp handle for vdev id %d", + __func__, resp_event->vdev_id); return -EINVAL; } diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index c991d8e40462..630f997f5283 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1994,7 +1994,7 @@ QDF_STATUS wma_process_ll_stats_clear_req(tp_wma_handle wma, } if (!wlan_vdev_get_dp_handle(vdev)) { - WMA_LOGE("%s: vdev_id %d handle is NULL", + WMA_LOGE("%s: vdev_id %d dp handle is NULL", __func__, clearReq->staId); return QDF_STATUS_E_FAILURE; }