From 97e8a711563a8a30000fc133d9fb7d04b5201788 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Fri, 29 Mar 2019 12:14:04 +0530 Subject: [PATCH] qcacld-3.0: Process eWNI_SME_DISCONNECT_DONE_IND even after stop bss If LIM initiate disconnect for a peer (eSmeCommandWmStatusChange) and at same time bss is stopped, disconnect may get processed after stop bss and thus will return from LIM as AP has already stopped. LIM will post eWNI_SME_DISCONNECT_DONE_IND to sme to remove the eSmeCommandWmStatusChange command from serialization active queue. But eWNI_SME_DISCONNECT_DONE_IND is not processed in CSR sub state eCSR_ROAM_SUBSTATE_STOP_BSS_REQ the command is not removed. Fix is to handle the eWNI_SME_DISCONNECT_DONE_IND in eCSR_ROAM_SUBSTATE_STOP_BSS_REQ state.Also allow hdd_cfg80211_del_station call during unload. Change-Id: I79cd1f413f2f9f12e6da6702098b782b6c156d24 CRs-Fixed: 2425724 --- core/hdd/src/wlan_hdd_cfg80211.c | 9 +-- core/sme/src/csr/csr_api_roam.c | 121 ++++++++++++++++--------------- 2 files changed, 66 insertions(+), 64 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index d00adce16f12..9173e441682c 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -19423,7 +19423,6 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, struct hdd_context *hdd_ctx; QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; struct hdd_hostapd_state *hapd_state; - int status; uint8_t sta_id; uint8_t *mac; mac_handle_t mac_handle; @@ -19443,10 +19442,10 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, adapter->vdev_id, adapter->device_mode); hdd_ctx = WLAN_HDD_GET_CTX(adapter); - status = wlan_hdd_validate_context(hdd_ctx); - - if (0 != status) - return status; + if (!hdd_ctx) { + hdd_err("hdd_ctx is NULL"); + return -EINVAL; + } mac = (uint8_t *) param->peerMacAddr.bytes; mac_handle = hdd_ctx->mac_handle; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 327f2d20d97f..1c50d400b1ca 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -9645,6 +9645,64 @@ csr_roam_roaming_state_start_bss_rsp_processor(struct mac_context *mac, pSmeStartBssRsp->sessionId); } +/** + * csr_roam_send_disconnect_done_indication() - Send disconnect ind to HDD. + * + * @mac_ctx: mac global context + * @msg_ptr: incoming message + * + * This function gives final disconnect event to HDD after all cleanup in + * lower layers is done. + * + * Return: None + */ +static void +csr_roam_send_disconnect_done_indication(struct mac_context *mac_ctx, + tSirSmeRsp *msg_ptr) +{ + struct sir_sme_discon_done_ind *discon_ind = + (struct sir_sme_discon_done_ind *)(msg_ptr); + struct csr_roam_info *roam_info; + struct csr_roam_session *session; + + roam_info = qdf_mem_malloc(sizeof(*roam_info)); + if (!roam_info) + return; + + sme_debug("DISCONNECT_DONE_IND RC:%d", discon_ind->reason_code); + + if (CSR_IS_SESSION_VALID(mac_ctx, discon_ind->session_id)) { + roam_info->reasonCode = discon_ind->reason_code; + roam_info->statusCode = eSIR_SME_STA_NOT_ASSOCIATED; + qdf_mem_copy(roam_info->peerMac.bytes, discon_ind->peer_mac, + ETH_ALEN); + + roam_info->rssi = mac_ctx->peer_rssi; + roam_info->tx_rate = mac_ctx->peer_txrate; + roam_info->rx_rate = mac_ctx->peer_rxrate; + roam_info->disassoc_reason = discon_ind->reason_code; + + csr_roam_call_callback(mac_ctx, discon_ind->session_id, + roam_info, 0, eCSR_ROAM_LOSTLINK, + eCSR_ROAM_RESULT_DISASSOC_IND); + session = CSR_GET_SESSION(mac_ctx, discon_ind->session_id); + if (session && + !CSR_IS_INFRA_AP(&session->connectedProfile)) + csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE, + discon_ind->session_id); + + } else { + sme_err("Inactive session %d", discon_ind->session_id); + } + + /* + * Release WM status change command as eWNI_SME_DISCONNECT_DONE_IND + * has been sent to HDD and there is nothing else left to do. + */ + csr_roam_wm_status_change_complete(mac_ctx, discon_ind->session_id); + qdf_mem_free(roam_info); +} + /** * csr_roaming_state_msg_processor() - process roaming messages * @mac: mac global context @@ -9766,6 +9824,10 @@ void csr_roaming_state_msg_processor(struct mac_context *mac, void *pMsgBuf) csr_roam_check_for_link_status_change(mac, pSmeRsp); break; + case eWNI_SME_DISCONNECT_DONE_IND: + csr_roam_send_disconnect_done_indication(mac, pSmeRsp); + break; + case eWNI_SME_UPPER_LAYER_ASSOC_CNF: { tSirSmeAssocIndToUpperLayerCnf *upper_layer_assoc_cnf = @@ -11296,65 +11358,6 @@ csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) qdf_mem_free(cmd); } -/** - * csr_roam_send_disconnect_done_indication() - Send disconnect ind to HDD. - * - * @mac_ctx: mac global context - * @msg_ptr: incoming message - * - * This function gives final disconnect event to HDD after all cleanup in - * lower layers is done. - * - * Return: None - */ -static void -csr_roam_send_disconnect_done_indication(struct mac_context *mac_ctx, tSirSmeRsp - *msg_ptr) -{ - struct sir_sme_discon_done_ind *discon_ind = - (struct sir_sme_discon_done_ind *)(msg_ptr); - struct csr_roam_info *roam_info; - struct csr_roam_session *session; - - roam_info = qdf_mem_malloc(sizeof(*roam_info)); - if (!roam_info) - return; - - sme_debug("eWNI_SME_DISCONNECT_DONE_IND RC:%d", - discon_ind->reason_code); - - if (CSR_IS_SESSION_VALID(mac_ctx, discon_ind->session_id)) { - roam_info->reasonCode = discon_ind->reason_code; - roam_info->statusCode = eSIR_SME_STA_NOT_ASSOCIATED; - qdf_mem_copy(roam_info->peerMac.bytes, discon_ind->peer_mac, - ETH_ALEN); - - roam_info->rssi = mac_ctx->peer_rssi; - roam_info->tx_rate = mac_ctx->peer_txrate; - roam_info->rx_rate = mac_ctx->peer_rxrate; - roam_info->disassoc_reason = discon_ind->reason_code; - - csr_roam_call_callback(mac_ctx, discon_ind->session_id, - roam_info, 0, eCSR_ROAM_LOSTLINK, - eCSR_ROAM_RESULT_DISASSOC_IND); - session = CSR_GET_SESSION(mac_ctx, discon_ind->session_id); - if (session && - !CSR_IS_INFRA_AP(&session->connectedProfile)) - csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE, - discon_ind->session_id); - - } else - sme_err("Inactive session %d", - discon_ind->session_id); - - /* - * Release WM status change command as eWNI_SME_DISCONNECT_DONE_IND - * has been sent to HDD and there is nothing else left to do. - */ - csr_roam_wm_status_change_complete(mac_ctx, discon_ind->session_id); - qdf_mem_free(roam_info); -} - static void csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) {