diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 6770f78f2ef2..d6e5ae4aeb51 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -1230,11 +1230,6 @@ 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/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index f096d1f7685d..5f29233bcd55 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -3303,19 +3303,19 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit) status = qdf_event_create(&phostapdBuf->qdf_event); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("Hostapd HDD qdf event init failed!!"); - goto error_release_sap_session; + goto error_deinit_sap_session; } status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("Hostapd HDD stop bss event init failed!!"); - goto error_release_sap_session; + goto error_deinit_sap_session; } status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("Hostapd HDD sta disassoc event init failed!!"); - goto error_release_sap_session; + goto error_deinit_sap_session; } /* Register as a wireless device */ @@ -3383,13 +3383,11 @@ error_release_wmm: error_release_sta_info: hdd_sta_info_deinit(&adapter->sta_info_list); error_release_softap_tx_rx: - hdd_softap_deinit_tx_rx(adapter); -error_release_sap_session: hdd_unregister_wext(adapter->dev); + hdd_softap_deinit_tx_rx(adapter); +error_deinit_sap_session: hdd_hostapd_deinit_sap_session(adapter); error_release_vdev: - QDF_BUG(!hdd_vdev_destroy(adapter)); - hdd_exit(); return status; } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 1e32e6edbc50..a3c255590c87 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5948,6 +5948,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, if (!wlan_sap_is_pre_cac_context(sap_ctx) && (hdd_ctx->sap_pre_cac_work.fn)) cds_flush_work(&hdd_ctx->sap_pre_cac_work); + wlansap_cleanup_cac_timer(sap_ctx); /* fallthrough */ @@ -6022,9 +6023,16 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, /* Reset WNI_CFG_PROBE_RSP Flags */ wlan_hdd_reset_prob_rspies(adapter); } - clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags); - qdf_mem_free(adapter->session.ap.beacon); - adapter->session.ap.beacon = NULL; + + /* + * Note to restart sap after SSR driver needs below information + * and is not cleared/freed on purpose in case of SAP SSR + */ + if (!cds_is_driver_recovering()) { + clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags); + qdf_mem_free(adapter->session.ap.beacon); + adapter->session.ap.beacon = NULL; + } /* Clear all the cached sta info */ hdd_clear_cached_sta_info(&adapter->cache_sta_info_list); @@ -6045,7 +6053,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, cancel_work_sync(&adapter->ipv6_notifier_work); #endif #endif - + sap_release_vdev_ref(WLAN_HDD_GET_SAP_CTX_PTR(adapter)); hdd_vdev_destroy(adapter); mutex_unlock(&hdd_ctx->sap_lock); @@ -6162,31 +6170,30 @@ static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) qdf_mc_timer_stop(&adapter->tx_flow_control_timer); } } +#else +static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) +{ +} #endif QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) { struct hdd_adapter *adapter; - struct hdd_station_ctx *sta_ctx; - struct qdf_mac_addr peer_macaddr; bool value; struct wlan_objmgr_vdev *vdev; hdd_enter(); - /* do not flush work if it is not created */ - if (hdd_ctx->sap_pre_cac_work.fn) - cds_flush_work(&hdd_ctx->sap_pre_cac_work); + ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); + hdd_for_each_adapter(hdd_ctx, adapter) { hdd_info("[SSR] reset adapter with device mode %s(%d)", qdf_opmode_str(adapter->device_mode), adapter->device_mode); -#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL - hdd_adapter_abort_tx_flow(adapter); -#endif + hdd_adapter_abort_tx_flow(adapter); if ((adapter->device_mode == QDF_STA_MODE) || (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { /* Stop tdls timers */ @@ -6195,9 +6202,8 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) hdd_notify_tdls_reset_adapter(vdev); hdd_objmgr_put_vdev(vdev); } - adapter->session.station.hdd_reassoc_scenario = false; } - ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); + if (value && adapter->device_mode == QDF_SAP_MODE) { wlan_hdd_netif_queue_control(adapter, @@ -6209,13 +6215,6 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) WLAN_CONTROL_PATH); } - if ((adapter->device_mode == QDF_P2P_GO_MODE || - adapter->device_mode == QDF_SAP_MODE) && - test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) { - hdd_sap_indicate_disconnect_for_sta(adapter); - clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags); - } - /* * Clear fc flag if it was set before SSR to avoid TX queues * permanently stopped after SSR. @@ -6228,73 +6227,19 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) WLAN_DATA_FLOW_CONTROL); hdd_reset_scan_operation(hdd_ctx, adapter); - hdd_deinit_tx_rx(adapter); - policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, - adapter->device_mode, adapter->vdev_id); - hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, - false); + if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { hdd_wmm_adapter_close(adapter); clear_bit(WMM_INIT_DONE, &adapter->event_flags); } - if (adapter->device_mode == QDF_STA_MODE) - hdd_clear_fils_connection_info(adapter); - - if (adapter->device_mode == QDF_SAP_MODE) { - wlansap_cleanup_cac_timer( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - /* - * If adapter is SAP, set session ID to invalid - * since SAP session will be cleanup during SSR. - */ - wlansap_set_invalid_session( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - } - - /* Release vdev ref count to avoid vdev object leak */ - if (adapter->device_mode == QDF_P2P_GO_MODE || - adapter->device_mode == QDF_SAP_MODE) - wlansap_release_vdev_ref( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); - - /* Delete connection peers if any to avoid peer object leaks */ - if (adapter->device_mode == QDF_STA_MODE || - adapter->device_mode == QDF_P2P_CLIENT_MODE) { - sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - qdf_copy_macaddr(&peer_macaddr, - &sta_ctx->conn_info.bssid); - - } - - hdd_nud_ignore_tracking(adapter, true); - hdd_nud_reset_tracking(adapter); - hdd_nud_flush_work(adapter); - hdd_mic_flush_work(adapter); - if (adapter->device_mode != QDF_SAP_MODE && adapter->device_mode != QDF_P2P_GO_MODE && adapter->device_mode != QDF_FTM_MODE) hdd_set_disconnect_status(adapter, false); - hdd_stop_tsf_sync(adapter); - - hdd_softap_deinit_tx_rx(adapter); - if (adapter->device_mode == QDF_SAP_MODE || - adapter->device_mode == QDF_P2P_GO_MODE) { - /* Clear all the cached sta info */ - hdd_clear_cached_sta_info( - &adapter->cache_sta_info_list); - hdd_sta_info_deinit(&adapter->sta_info_list); - hdd_sta_info_deinit(&adapter->cache_sta_info_list); - } - - hdd_deregister_hl_netdev_fc_timer(adapter); - hdd_deregister_tx_flow_control(adapter); - - /* Destroy vdev which will be recreated during reinit. */ - hdd_vdev_destroy(adapter); + hdd_stop_adapter(hdd_ctx, adapter); } hdd_exit(); @@ -10540,8 +10485,17 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) ret = hdd_vdev_create(adapter); if (ret) { hdd_err("failed to create vdev, status:%d", ret); - hdd_sap_destroy_ctx(adapter); - return ret; + goto sap_destroy_ctx; + } + + status = sap_acquire_vdev_ref(hdd_ctx->psoc, + WLAN_HDD_GET_SAP_CTX_PTR(adapter), + adapter->vdev_id); + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_err("Failed to get vdev ref for sap for session_id: %u", + adapter->vdev_id); + ret = qdf_status_to_os_return(status); + goto sap_vdev_destroy; } if (adapter->device_mode == QDF_SAP_MODE) { @@ -10563,7 +10517,8 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) if (QDF_STATUS_SUCCESS != status) { hdd_err("Error Initializing the AP mode: %d", status); - return qdf_status_to_os_return(status); + ret = qdf_status_to_os_return(status); + goto sap_release_ref; } hdd_register_tx_flow_control(adapter, @@ -10576,6 +10531,14 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) hdd_exit(); return 0; + +sap_release_ref: + sap_release_vdev_ref(WLAN_HDD_GET_SAP_CTX_PTR(adapter)); +sap_vdev_destroy: + hdd_vdev_destroy(adapter); +sap_destroy_ctx: + hdd_sap_destroy_ctx(adapter); + return ret; } #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index b6294e12cd42..e445a4df98a0 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -1472,6 +1472,29 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx); */ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx); +/** + * sap_acquire_vdev_ref() - Increment reference count for vdev object + * @psoc: Object Manager PSoC object + * @sap_ctx: to store vdev object pointer + * @session_id: used to get vdev object + * + * This function is used to increment vdev object reference count and store + * vdev pointer in sap_ctx. + * + * Return: QDF_STATUS_SUCCESS - If able to get vdev object reference + * else qdf status failure codes + */ +QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc, + struct sap_context *sap_ctx, + uint8_t session_id); + +/** + * sap_release_vdev_ref() - Decrement reference count for vdev object + * @sap_ctx: for which vdev reference is to be decremented + * + * Return: None + */ +void sap_release_vdev_ref(struct sap_context *sap_ctx); #ifdef __cplusplus } #endif diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index fd78e8015a68..83f4a7a81a24 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -1083,7 +1083,7 @@ static QDF_STATUS sap_clear_global_dfs_param(mac_handle_t mac_handle) return QDF_STATUS_SUCCESS; } -QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac, +QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc, struct sap_context *sap_ctx, uint8_t session_id) { @@ -1095,8 +1095,7 @@ QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac, return QDF_STATUS_E_FAULT; } - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, - session_id, + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, WLAN_LEGACY_SAP_ID); if (!vdev) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, @@ -1112,10 +1111,16 @@ void sap_release_vdev_ref(struct sap_context *sap_ctx) { struct wlan_objmgr_vdev *vdev; + if (!sap_ctx) { + sap_err("Invalid SAP pointer"); + return; + } + vdev = sap_ctx->vdev; - sap_ctx->vdev = NULL; - if (vdev) + if (vdev) { + sap_ctx->vdev = NULL; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID); + } } QDF_STATUS sap_set_session_param(mac_handle_t mac_handle, @@ -1124,7 +1129,6 @@ QDF_STATUS sap_set_session_param(mac_handle_t mac_handle, { struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); int i; - QDF_STATUS status; sapctx->sessionId = session_id; sapctx->is_pre_cac_on = false; @@ -1137,14 +1141,6 @@ QDF_STATUS sap_set_session_param(mac_handle_t mac_handle, mac_ctx->sap.sapCtxList[i].sap_context = NULL; } - status = sap_acquire_vdev_ref(mac_ctx, sapctx, session_id); - if (!QDF_IS_STATUS_SUCCESS(status)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("sap context init failed for session_id: %u"), - session_id); - return status; - } - mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx; mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = sapctx->csr_roamProfile.csrPersona; @@ -1164,8 +1160,6 @@ QDF_STATUS sap_clear_session_param(mac_handle_t mac_handle, if (sapctx->sessionId >= SAP_MAX_NUM_SESSION) return QDF_STATUS_E_FAILURE; - sap_release_vdev_ref(sapctx); - mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL; mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = QDF_MAX_NO_OF_MODE; diff --git a/core/sap/src/sap_internal.h b/core/sap/src/sap_internal.h index 1b698984b764..48ea78769ff1 100644 --- a/core/sap/src/sap_internal.h +++ b/core/sap/src/sap_internal.h @@ -479,29 +479,4 @@ bool sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context, uint8_t channel_number, ePhyChanBondState bond_state); - -/** - * sap_acquire_vdev_ref() - Increment reference count for vdev object - * @mac: mac handle - * @sap_ctx: to store vdev object pointer - * @session_id: used to get vdev object - * - * This function is used to increment vdev object reference count and store - * vdev pointer in sap_ctx. - * - * Return: QDF_STATUS_SUCCESS - If able to get vdev object reference - * else qdf status failure codes - */ -QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac, - struct sap_context *sap_ctx, - uint8_t session_id); - -/** - * sap_release_vdev_ref() - Decrement reference count for vdev object - * @sap_ctx: for which vdev reference is to be decremented - * - * Return: None - */ -void sap_release_vdev_ref(struct sap_context *sap_ctx); - #endif diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index f9ec784f2a2b..20f12655860e 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2669,18 +2669,6 @@ 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); - #ifdef FEATURE_ANI_LEVEL_REQUEST /** * wma_send_ani_level_request() - Send get ani level cmd to WMI diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index c20938861251..69a63c6cb1d0 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -601,9 +601,6 @@ out: wma_vdev_deinit(iface); qdf_mem_zero(iface, sizeof(*iface)); wma_vdev_init(iface); - - del_vdev_req_param->status = status; - wma_send_vdev_del_resp(del_vdev_req_param); return status; } @@ -679,95 +676,6 @@ error: return qdf_status; } -/** - * wma_force_objmgr_vdev_peer_cleanup() - Cleanup ObjMgr Vdev peers during SSR - * @wma_handle: WMA handle - * @iface: wma interface txrx node - * - * Return: none - */ -static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma, - struct wma_txrx_node *iface) -{ - struct wlan_objmgr_vdev *vdev; - 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; - - /* - * 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_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; - - peer_list = &vdev->vdev_objmgr.wlan_peer_list; - if (!peer_list) { - WMA_LOGE("%s: peer_list is NULL", __func__); - return; - } - - /* - * We get refcount for each peer first, logically delete it and - * then release the refcount so that the peer is physically - * deleted. - */ - peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list, - WLAN_LEGACY_WMA_ID); - while (peer) { - WMA_LOGD("%s: Deleting Peer %pM", - __func__, peer->macaddr); - wlan_objmgr_peer_obj_delete(peer); - peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev, - peer_list, peer, WLAN_LEGACY_WMA_ID); - wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID); - peer = peer_next; - } - - /* Force delete all the peers, set the wma interface peer_count to 0 */ - iface->peer_count = 0; -} - -static 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); -} - -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) { @@ -908,18 +816,6 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, goto send_rsp; } - /* - * In SSR case or if FW is down we only need to clean up the host. - * There is no need to destroy vdev in firmware since it - * has already asserted. - * Cleanup the ObjMgr Peers for the current vdev and detach the - * CDP Vdev. - */ - if (!cds_is_target_ready()) { - wma_release_vdev_and_peer_ref(wma_handle, iface); - goto send_rsp; - } - status = wma_check_for_deffered_peer_delete(wma_handle, pdel_vdev_req_param); if (QDF_IS_STATUS_ERROR(status)) @@ -934,7 +830,7 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, if (QDF_IS_STATUS_ERROR(status)) { wma_err("Failed to send self peer delete:%d", status); - return status; + goto send_rsp; } if (iface->type != WMI_VDEV_TYPE_MONITOR) @@ -947,6 +843,9 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, pdel_vdev_req_param); } + if (QDF_IS_STATUS_ERROR(status)) + goto send_rsp; + return status; send_fail_rsp: @@ -5254,6 +5153,7 @@ void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id) if (wma_send_vdev_stop_to_fw(wma, vdev_id)) { WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__); status = QDF_STATUS_E_FAILURE; + qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); goto detach_peer; } WMA_LOGD("%s: bssid %pM vdev_id %d", diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 56402eb74f34..195767c244e8 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2618,11 +2618,6 @@ void wma_vdev_deinit(struct wma_txrx_node *vdev) vdev->staKeyParams = NULL; } - if (vdev->del_staself_req) { - qdf_mem_free(vdev->del_staself_req); - vdev->del_staself_req = NULL; - } - if (vdev->psnr_req) { qdf_mem_free(vdev->psnr_req); vdev->psnr_req = NULL; @@ -4303,7 +4298,7 @@ QDF_STATUS wma_wmi_service_close(void) { void *cds_ctx; tp_wma_handle wma_handle; - int i; + uint8_t i; WMA_LOGD("%s: Enter", __func__);