diff options
| author | Varun Reddy Yeturu <varunreddy.yeturu@codeaurora.org> | 2017-12-15 16:08:13 -0800 |
|---|---|---|
| committer | snandini <snandini@codeaurora.org> | 2018-02-20 14:37:53 -0800 |
| commit | 3bc1d1cbcb2d47ab8391af6ff4a5e78707ca789f (patch) | |
| tree | cbb5ba1a42f32fff6b17d5be4a5684dd24b66538 | |
| parent | e70bbd09e6e13bd6e69ec98520df003317d97bcf (diff) | |
qcacld-3.0: Handle disassoc and deauth during LFR3 roaming
Ignore the disassociation and deauthentication requests from
the old AP once roaming is in progress. Memorize the
received disassoc/deauth. If the roaming is not successful
and current AP's connection is retained, then the earlier
received disassoc/deauth can be honored and disconnect can
be triggered internally.
Change-Id: I5fa4d154c17e08904d839b8a889020680d662021
CRs-Fixed: 2160681
| -rw-r--r-- | core/mac/src/pe/include/lim_api.h | 6 | ||||
| -rw-r--r-- | core/mac/src/pe/include/lim_session.h | 4 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_api.c | 45 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_process_deauth_frame.c | 250 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_process_disassoc_frame.c | 109 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_types.h | 43 | ||||
| -rw-r--r-- | core/wma/inc/wma.h | 3 | ||||
| -rw-r--r-- | core/wma/inc/wma_types.h | 6 | ||||
| -rw-r--r-- | core/wma/src/wma_mgmt.c | 3 | ||||
| -rw-r--r-- | core/wma/src/wma_scan_roam.c | 6 |
10 files changed, 321 insertions, 154 deletions
diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h index 64215ed8c4b5..5994d95accee 100644 --- a/core/mac/src/pe/include/lim_api.h +++ b/core/mac/src/pe/include/lim_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -214,11 +214,11 @@ tMgmtFrmDropReason lim_is_pkt_candidate_for_drop(tpAniSirGlobal pMac, #ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx, struct sSirSmeRoamOffloadSynchInd *roam_sync_ind_ptr, - tpSirBssDescription bss_desc_ptr); + tpSirBssDescription bss_desc_ptr, enum sir_roam_op_code reason); #else static inline QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx, struct sSirSmeRoamOffloadSynchInd *roam_sync_ind_ptr, - tpSirBssDescription bss_desc_ptr) + tpSirBssDescription bss_desc_ptr, enum sir_roam_op_code reason) { return QDF_STATUS_E_NOSUPPORT; } diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 7dd6ff1a3661..2e48bf1b1c1a 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -508,6 +508,10 @@ typedef struct sPESession /* Added to Support BT-AMP */ bool ch_switch_in_progress; /* previous auth frame's sequence number */ uint16_t prev_auth_seq_num; + bool fw_roaming_started; + bool recvd_deauth_while_roaming; + bool recvd_disassoc_while_roaming; + bool deauth_disassoc_rc; } tPESession, *tpPESession; /*------------------------------------------------------------------------- diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 0cb47a7fd379..594191098171 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -2004,6 +2004,7 @@ static inline void lim_copy_and_free_hlp_data_from_session( * @mac_ctx: MAC Context * @roam_sync_ind_ptr: Roam synch indication buffer pointer * @bss_desc: BSS Descriptor pointer + * @reason: Reason for calling callback which decides the action to be taken. * * This is a PE level callback called from WMA to complete the roam synch * propagation at PE level and also fill the BSS descriptor which will be @@ -2013,7 +2014,7 @@ static inline void lim_copy_and_free_hlp_data_from_session( */ QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx, roam_offload_synch_ind *roam_sync_ind_ptr, - tpSirBssDescription bss_desc) + tpSirBssDescription bss_desc, enum sir_roam_op_code reason) { tpPESession session_ptr; tpPESession ft_session_ptr; @@ -2028,20 +2029,54 @@ QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx, pe_err("LFR3:roam_sync_ind_ptr is NULL"); return status; } - pe_debug("LFR3:Received WMA_ROAM_OFFLOAD_SYNCH_IND LFR3:auth: %d vdevId: %d", - roam_sync_ind_ptr->authStatus, roam_sync_ind_ptr->roamedVdevId); - lim_print_mac_addr(mac_ctx, roam_sync_ind_ptr->bssid.bytes, - QDF_TRACE_LEVEL_DEBUG); session_ptr = pe_find_session_by_sme_session_id(mac_ctx, roam_sync_ind_ptr->roamedVdevId); if (session_ptr == NULL) { pe_err("LFR3:Unable to find session"); return status; } + if (!LIM_IS_STA_ROLE(session_ptr)) { pe_err("LFR3:session is not in STA mode"); return status; } + + pe_debug("LFR3: PE callback reason: %d", reason); + switch (reason) { + case SIR_ROAMING_START: + session_ptr->fw_roaming_started = true; + return QDF_STATUS_SUCCESS; + case SIR_ROAMING_ABORT: + session_ptr->fw_roaming_started = false; + /* + * If there was a disassoc or deauth that was received + * during roaming and it was not honored, then we have + * to internally initiate a disconnect because with + * ROAM_ABORT we come back to original AP. + */ + if (session_ptr->recvd_deauth_while_roaming) + lim_perform_deauth(mac_ctx, session_ptr, + session_ptr->deauth_disassoc_rc, + session_ptr->bssId, 0); + if (session_ptr->recvd_disassoc_while_roaming) { + lim_disassoc_tdls_peers(mac_ctx, session_ptr, + session_ptr->bssId); + lim_perform_disassoc(mac_ctx, 0, + session_ptr->deauth_disassoc_rc, + session_ptr, session_ptr->bssId); + } + return QDF_STATUS_SUCCESS; + case SIR_ROAM_SYNCH_PROPAGATION: + session_ptr->fw_roaming_started = false; + break; + default: + return status; + } + + pe_debug("LFR3:Received WMA_ROAM_OFFLOAD_SYNCH_IND LFR3:auth: %d vdevId: %d", + roam_sync_ind_ptr->authStatus, roam_sync_ind_ptr->roamedVdevId); + lim_print_mac_addr(mac_ctx, roam_sync_ind_ptr->bssid.bytes, + QDF_TRACE_LEVEL_DEBUG); /* * If deauth from AP already in progress, ignore Roam Synch Indication * from firmware. diff --git a/core/mac/src/pe/lim/lim_process_deauth_frame.c b/core/mac/src/pe/lim/lim_process_deauth_frame.c index 721b1adcabb9..02837a61cf1e 100644 --- a/core/mac/src/pe/lim/lim_process_deauth_frame.c +++ b/core/mac/src/pe/lim/lim_process_deauth_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -71,11 +71,8 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, tpPESession psessionEntry) { uint8_t *pBody; - uint16_t aid, reasonCode; + uint16_t reasonCode; tpSirMacMgmtHdr pHdr; - tLimMlmAssocCnf mlmAssocCnf; - tLimMlmDeauthInd mlmDeauthInd; - tpDphHashNode pStaDs; tpPESession pRoamSessionEntry = NULL; uint8_t roamSessionId; #ifdef WLAN_FEATURE_11W @@ -251,8 +248,30 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, pe_find_session_by_bssid(pMac, psessionEntry->limReAssocbssId, &roamSessionId); - if (lim_is_reassoc_in_progress(pMac, psessionEntry) - || lim_is_reassoc_in_progress(pMac, pRoamSessionEntry)) { + if (lim_is_reassoc_in_progress(pMac, psessionEntry) || + lim_is_reassoc_in_progress(pMac, pRoamSessionEntry) || + psessionEntry->fw_roaming_started) { + /* + * For LFR3, the roaming bssid is not known during ROAM_START, + * so check if the deauth is received from current AP when + * roaming is being done in the firmware + */ + if (psessionEntry->fw_roaming_started && + IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) { + pe_debug("LFR3: Drop deauth frame from connected AP"); + /* + * recvd_deauth_while_roaming will be stored in the + * current AP session amd if roaming has been aborted + * for some reason and come back to same AP, then issue + * a disconnect internally if this flag is true. There + * is no need to reset this flag to false, because if + * roaming succeeds, then this session gets deleted and + * new session is created. + */ + psessionEntry->recvd_deauth_while_roaming = true; + psessionEntry->deauth_disassoc_rc = reasonCode; + return; + } if (!IS_REASSOC_BSSID(pMac, pHdr->sa, psessionEntry)) { pe_debug("Rcv Deauth from unknown/different " "AP while ReAssoc. Ignore " MAC_ADDRESS_STR @@ -297,14 +316,30 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, } } - pStaDs = - dph_lookup_hash_entry(pMac, pHdr->sa, &aid, - &psessionEntry->dph.dphHashTable); + lim_perform_deauth(pMac, psessionEntry, reasonCode, pHdr->sa, + frame_rssi); + +} /*** end lim_process_deauth_frame() ***/ + +void lim_perform_deauth(tpAniSirGlobal mac_ctx, tpPESession pe_session, + uint16_t rc, tSirMacAddr addr, int32_t frame_rssi) +{ + tLimMlmDeauthInd mlmDeauthInd; + tLimMlmAssocCnf mlmAssocCnf; + uint16_t aid; + tpDphHashNode sta_ds; + + sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid, + &pe_session->dph.dphHashTable); + if (sta_ds == NULL) { + pe_debug("Hash entry not found"); + return; + } /* Check for pre-assoc states */ - switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) { + switch (GET_LIM_SYSTEM_ROLE(pe_session)) { case eLIM_STA_ROLE: - switch (psessionEntry->limMlmState) { + switch (pe_session->limMlmState) { case eLIM_MLM_WT_AUTH_FRAME2_STATE: /** * AP sent Deauth frame while waiting @@ -314,34 +349,34 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, pe_debug("received Deauth frame state %X with failure " "code %d from " MAC_ADDRESS_STR, - psessionEntry->limMlmState, reasonCode, - MAC_ADDR_ARRAY(pHdr->sa)); + pe_session->limMlmState, rc, + MAC_ADDR_ARRAY(addr)); - lim_restore_from_auth_state(pMac, - eSIR_SME_DEAUTH_WHILE_JOIN, - reasonCode, psessionEntry); + lim_restore_from_auth_state(mac_ctx, + eSIR_SME_DEAUTH_WHILE_JOIN, + rc, pe_session); return; case eLIM_MLM_AUTHENTICATED_STATE: pe_debug("received Deauth frame state %X with " - "reasonCode=%d from " MAC_ADDRESS_STR, - psessionEntry->limMlmState, reasonCode, - MAC_ADDR_ARRAY(pHdr->sa)); + "reasonCode=%d from " MAC_ADDRESS_STR, + pe_session->limMlmState, rc, + MAC_ADDR_ARRAY(addr)); /* / Issue Deauth Indication to SME. */ qdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr, - pHdr->sa, sizeof(tSirMacAddr)); - mlmDeauthInd.reasonCode = reasonCode; + addr, sizeof(tSirMacAddr)); + mlmDeauthInd.reasonCode = rc; - psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + pe_session->limMlmState = eLIM_MLM_IDLE_STATE; MTRACE(mac_trace - (pMac, TRACE_CODE_MLM_STATE, - psessionEntry->peSessionId, - psessionEntry->limMlmState)); + (mac_ctx, TRACE_CODE_MLM_STATE, + pe_session->peSessionId, + pe_session->limMlmState)); - lim_post_sme_message(pMac, - LIM_MLM_DEAUTH_IND, - (uint32_t *) &mlmDeauthInd); + lim_post_sme_message(mac_ctx, + LIM_MLM_DEAUTH_IND, + (uint32_t *) &mlmDeauthInd); return; case eLIM_MLM_WT_ASSOC_RSP_STATE: @@ -351,102 +386,102 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, * if any and issue ASSOC_CNF to SME. */ pe_debug("received Deauth frame state %X with " - "reasonCode=%d from " MAC_ADDRESS_STR, - psessionEntry->limMlmState, reasonCode, - MAC_ADDR_ARRAY(pHdr->sa)); - if (lim_search_pre_auth_list(pMac, pHdr->sa)) - lim_delete_pre_auth_node(pMac, pHdr->sa); - - if (psessionEntry->pLimMlmJoinReq) { - qdf_mem_free(psessionEntry->pLimMlmJoinReq); - psessionEntry->pLimMlmJoinReq = NULL; + "reasonCode=%d from " MAC_ADDRESS_STR, + pe_session->limMlmState, rc, + MAC_ADDR_ARRAY(addr)); + if (lim_search_pre_auth_list(mac_ctx, addr)) + lim_delete_pre_auth_node(mac_ctx, addr); + + if (pe_session->pLimMlmJoinReq) { + qdf_mem_free(pe_session->pLimMlmJoinReq); + pe_session->pLimMlmJoinReq = NULL; } mlmAssocCnf.resultCode = eSIR_SME_DEAUTH_WHILE_JOIN; - mlmAssocCnf.protStatusCode = reasonCode; + mlmAssocCnf.protStatusCode = rc; /* PE session Id */ - mlmAssocCnf.sessionId = psessionEntry->peSessionId; + mlmAssocCnf.sessionId = pe_session->peSessionId; - psessionEntry->limMlmState = - psessionEntry->limPrevMlmState; + pe_session->limMlmState = + pe_session->limPrevMlmState; MTRACE(mac_trace - (pMac, TRACE_CODE_MLM_STATE, - psessionEntry->peSessionId, - psessionEntry->limMlmState)); + (mac_ctx, TRACE_CODE_MLM_STATE, + pe_session->peSessionId, + pe_session->limMlmState)); /* Deactive Association response timeout */ - lim_deactivate_and_change_timer(pMac, - eLIM_ASSOC_FAIL_TIMER); + lim_deactivate_and_change_timer(mac_ctx, + eLIM_ASSOC_FAIL_TIMER); - lim_post_sme_message(pMac, - LIM_MLM_ASSOC_CNF, - (uint32_t *) &mlmAssocCnf); + lim_post_sme_message(mac_ctx, + LIM_MLM_ASSOC_CNF, + (uint32_t *) &mlmAssocCnf); return; case eLIM_MLM_WT_ADD_STA_RSP_STATE: - psessionEntry->fDeauthReceived = true; + pe_session->fDeauthReceived = true; pe_debug("Received Deauth frame in state %X with Reason " - "Code %d from Peer" MAC_ADDRESS_STR, - psessionEntry->limMlmState, reasonCode, - MAC_ADDR_ARRAY(pHdr->sa)); + "Code %d from Peer" MAC_ADDRESS_STR, + pe_session->limMlmState, rc, + MAC_ADDR_ARRAY(addr)); return; case eLIM_MLM_IDLE_STATE: case eLIM_MLM_LINK_ESTABLISHED_STATE: #ifdef FEATURE_WLAN_TDLS - if ((NULL != pStaDs) - && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) { + if ((NULL != sta_ds) + && (STA_ENTRY_TDLS_PEER == sta_ds->staType)) { pe_err("received Deauth frame in state %X with " "reason code %d from Tdls peer" MAC_ADDRESS_STR, - psessionEntry->limMlmState, reasonCode, - MAC_ADDR_ARRAY(pHdr->sa)); - lim_send_sme_tdls_del_sta_ind(pMac, pStaDs, - psessionEntry, - reasonCode); - return; + pe_session->limMlmState, rc, + MAC_ADDR_ARRAY(addr)); + lim_send_sme_tdls_del_sta_ind(mac_ctx, sta_ds, + pe_session, + rc); + return; } else { - /* - * Delete all the TDLS peers only if Deauth - * is received from the AP - */ - if (IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) - lim_delete_tdls_peers(pMac, psessionEntry); + /* + * Delete all the TDLS peers only if Deauth + * is received from the AP + */ + if (IS_CURRENT_BSSID(mac_ctx, addr, pe_session)) + lim_delete_tdls_peers(mac_ctx, pe_session); #endif /** * This could be Deauthentication frame from * a BSS with which pre-authentication was * performed. Delete Pre-auth entry if found. */ - if (lim_search_pre_auth_list(pMac, pHdr->sa)) - lim_delete_pre_auth_node(pMac, pHdr->sa); + if (lim_search_pre_auth_list(mac_ctx, addr)) + lim_delete_pre_auth_node(mac_ctx, addr); #ifdef FEATURE_WLAN_TDLS - } + } #endif break; case eLIM_MLM_WT_REASSOC_RSP_STATE: pe_err("received Deauth frame state %X with " "reasonCode=%d from " MAC_ADDRESS_STR, - psessionEntry->limMlmState, reasonCode, - MAC_ADDR_ARRAY(pHdr->sa)); + pe_session->limMlmState, rc, + MAC_ADDR_ARRAY(addr)); break; case eLIM_MLM_WT_FT_REASSOC_RSP_STATE: pe_err("received Deauth frame in FT state %X with " "reasonCode=%d from " MAC_ADDRESS_STR, - psessionEntry->limMlmState, reasonCode, - MAC_ADDR_ARRAY(pHdr->sa)); + pe_session->limMlmState, rc, + MAC_ADDR_ARRAY(addr)); break; default: pe_err("received Deauth frame in state %X with " "reasonCode=%d from " MAC_ADDRESS_STR, - psessionEntry->limMlmState, reasonCode, - MAC_ADDR_ARRAY(pHdr->sa)); + pe_session->limMlmState, rc, + MAC_ADDR_ARRAY(addr)); return; } break; @@ -458,7 +493,6 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, break; default: - return; } /* end switch (pMac->lim.gLimSystemRole) */ @@ -466,30 +500,30 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, * Extract 'associated' context for STA, if any. * This is maintained by DPH and created by LIM. */ - if (NULL == pStaDs) { - pe_err("pStaDs is NULL"); + if (NULL == sta_ds) { + pe_err("sta_ds is NULL"); return; } - if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || - (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) { + if ((sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || + (sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) { /** * Already in the process of deleting context for the peer * and received Deauthentication frame. Log and Ignore. */ pe_err("received Deauth frame from peer that is in state %X, addr " - MAC_ADDRESS_STR, pStaDs->mlmStaContext.mlmState, - MAC_ADDR_ARRAY(pHdr->sa)); + MAC_ADDRESS_STR, sta_ds->mlmStaContext.mlmState, + MAC_ADDR_ARRAY(addr)); return; } - pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode; - pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DEAUTH; + sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes) rc; + sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DEAUTH; /* / Issue Deauth Indication to SME. */ qdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr, - pStaDs->staAddr, sizeof(tSirMacAddr)); + sta_ds->staAddr, sizeof(tSirMacAddr)); mlmDeauthInd.reasonCode = - (uint8_t) pStaDs->mlmStaContext.disassocReason; + (uint8_t) sta_ds->mlmStaContext.disassocReason; mlmDeauthInd.deauthTrigger = eLIM_PEER_ENTITY_DEAUTH; /* @@ -498,18 +532,18 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, * failure result code. SME will post the disconnect to the * supplicant and the latter would start a fresh assoc. */ - if (lim_is_reassoc_in_progress(pMac, psessionEntry)) { + if (lim_is_reassoc_in_progress(mac_ctx, pe_session)) { /** * AP may have 'aged-out' our Pre-auth * context. Delete local pre-auth context * if any and issue REASSOC_CNF to SME. */ - if (lim_search_pre_auth_list(pMac, pHdr->sa)) - lim_delete_pre_auth_node(pMac, pHdr->sa); + if (lim_search_pre_auth_list(mac_ctx, addr)) + lim_delete_pre_auth_node(mac_ctx, addr); - if (psessionEntry->limAssocResponseData) { - qdf_mem_free(psessionEntry->limAssocResponseData); - psessionEntry->limAssocResponseData = NULL; + if (pe_session->limAssocResponseData) { + qdf_mem_free(pe_session->limAssocResponseData); + pe_session->limAssocResponseData = NULL; } pe_debug("Rcv Deauth from ReAssoc AP Issue REASSOC_CNF"); @@ -519,29 +553,29 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, * Using eSIR_SME_FT_REASSOC_FAILURE does not seem to clean-up * properly and we end up seeing "transmit queue timeout". */ - lim_post_reassoc_failure(pMac, - eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE, - eSIR_MAC_UNSPEC_FAILURE_STATUS, - psessionEntry); + lim_post_reassoc_failure(mac_ctx, + eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE, + eSIR_MAC_UNSPEC_FAILURE_STATUS, + pe_session); return; } /* reset the deauthMsgCnt here since we are able to Process * the deauth frame and sending up the indication as well */ - if (psessionEntry->deauthmsgcnt != 0) - psessionEntry->deauthmsgcnt = 0; + if (pe_session->deauthmsgcnt != 0) + pe_session->deauthmsgcnt = 0; - if (LIM_IS_STA_ROLE(psessionEntry)) - wma_tx_abort(psessionEntry->smeSessionId); + if (LIM_IS_STA_ROLE(pe_session)) + wma_tx_abort(pe_session->smeSessionId); - lim_update_lost_link_info(pMac, psessionEntry, frame_rssi); + lim_update_lost_link_info(mac_ctx, pe_session, frame_rssi); /* / Deauthentication from peer MAC entity */ - if (LIM_IS_STA_ROLE(psessionEntry)) - lim_post_sme_message(pMac, LIM_MLM_DEAUTH_IND, - (uint32_t *) &mlmDeauthInd); + if (LIM_IS_STA_ROLE(pe_session)) + lim_post_sme_message(mac_ctx, LIM_MLM_DEAUTH_IND, + (uint32_t *) &mlmDeauthInd); /* send eWNI_SME_DEAUTH_IND to SME */ - lim_send_sme_deauth_ind(pMac, pStaDs, psessionEntry); + lim_send_sme_deauth_ind(mac_ctx, sta_ds, pe_session); return; -} /*** end lim_process_deauth_frame() ***/ +} diff --git a/core/mac/src/pe/lim/lim_process_disassoc_frame.c b/core/mac/src/pe/lim/lim_process_disassoc_frame.c index 79344deabb89..c8ae79fc8618 100644 --- a/core/mac/src/pe/lim/lim_process_disassoc_frame.c +++ b/core/mac/src/pe/lim/lim_process_disassoc_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -77,7 +77,6 @@ lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, uint16_t aid, reasonCode; tpSirMacMgmtHdr pHdr; tpDphHashNode pStaDs; - tLimMlmDisassocInd mlmDisassocInd; #ifdef WLAN_FEATURE_11W uint32_t frameLen; #endif @@ -202,13 +201,25 @@ lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, /** If we are in the Wait for ReAssoc Rsp state */ if (lim_is_reassoc_in_progress(pMac, psessionEntry)) { + /* + * For LFR3, the roaming bssid is not known during ROAM_START, + * so check if the disassoc is received from current AP when + * roaming is being done in the firmware + */ + if (psessionEntry->fw_roaming_started && + IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) { + pe_debug("Dropping disassoc frame from connected AP"); + psessionEntry->recvd_disassoc_while_roaming = true; + psessionEntry->deauth_disassoc_rc = reasonCode; + return; + } /** If we had received the DisAssoc from, * a. the Current AP during ReAssociate to different AP in same ESS * b. Unknown AP * drop/ignore the DisAssoc received */ if (!IS_REASSOC_BSSID(pMac, pHdr->sa, psessionEntry)) { - pe_err("Ignore the DisAssoc received, while Processing ReAssoc with different/unknown AP"); + pe_err("Ignore DisAssoc while Processing ReAssoc"); return; } /** If the Disassoc is received from the new AP to which we tried to ReAssociate @@ -286,20 +297,7 @@ lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, MAC_ADDR_ARRAY(pHdr->sa)); return; } -#ifdef FEATURE_WLAN_TDLS - /** - * Delete all the TDLS peers only if Disassoc is received - * from the AP - */ - if ((LIM_IS_STA_ROLE(psessionEntry)) && - ((pStaDs->mlmStaContext.mlmState == - eLIM_MLM_LINK_ESTABLISHED_STATE) || - (pStaDs->mlmStaContext.mlmState == - eLIM_MLM_IDLE_STATE)) && - (IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry))) - lim_delete_tdls_peers(pMac, psessionEntry); -#endif - + lim_disassoc_tdls_peers(pMac, psessionEntry, pHdr->sa); if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) { /** * Requesting STA is in some 'transient' state? @@ -315,20 +313,65 @@ lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, } /* if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) */ - pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC; - pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode; + lim_perform_disassoc(pMac, frame_rssi, reasonCode, + psessionEntry, pHdr->sa); + +} /*** end lim_process_disassoc_frame() ***/ + +#ifdef FEATURE_WLAN_TDLS +void lim_disassoc_tdls_peers(tpAniSirGlobal mac_ctx, + tpPESession pe_session, tSirMacAddr addr) +{ + tpDphHashNode sta_ds; + uint16_t aid; + + sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid, + &pe_session->dph.dphHashTable); + if (sta_ds == NULL) { + pe_debug("Hash entry not found"); + return; + } + /** + * Delete all the TDLS peers only if Disassoc is received + * from the AP + */ + if ((LIM_IS_STA_ROLE(pe_session)) && + ((sta_ds->mlmStaContext.mlmState == + eLIM_MLM_LINK_ESTABLISHED_STATE) || + (sta_ds->mlmStaContext.mlmState == + eLIM_MLM_IDLE_STATE)) && + (IS_CURRENT_BSSID(mac_ctx, addr, pe_session))) + lim_delete_tdls_peers(mac_ctx, pe_session); +} +#endif + +void lim_perform_disassoc(tpAniSirGlobal mac_ctx, int32_t frame_rssi, + uint16_t rc, tpPESession pe_session, tSirMacAddr addr) +{ + tLimMlmDisassocInd mlmDisassocInd; + uint16_t aid; + tpDphHashNode sta_ds; + + sta_ds = dph_lookup_hash_entry(mac_ctx, addr, &aid, + &pe_session->dph.dphHashTable); + if (sta_ds == NULL) { + pe_debug("Hash entry not found"); + return; + } + sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC; + sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes) rc; /* Issue Disassoc Indication to SME. */ qdf_mem_copy((uint8_t *) &mlmDisassocInd.peerMacAddr, - (uint8_t *) pStaDs->staAddr, sizeof(tSirMacAddr)); + (uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr)); mlmDisassocInd.reasonCode = - (uint8_t) pStaDs->mlmStaContext.disassocReason; + (uint8_t) sta_ds->mlmStaContext.disassocReason; mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC; /* Update PE session Id */ - mlmDisassocInd.sessionId = psessionEntry->peSessionId; + mlmDisassocInd.sessionId = pe_session->peSessionId; - if (lim_is_reassoc_in_progress(pMac, psessionEntry)) { + if (lim_is_reassoc_in_progress(mac_ctx, pe_session)) { /* If we're in the middle of ReAssoc and received disassoc from * the ReAssoc AP, then notify SME by sending REASSOC_RSP with @@ -337,22 +380,22 @@ lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, */ pe_debug("received Disassoc from AP while waiting for Reassoc Rsp"); - if (psessionEntry->limAssocResponseData) { - qdf_mem_free(psessionEntry->limAssocResponseData); - psessionEntry->limAssocResponseData = NULL; + if (pe_session->limAssocResponseData) { + qdf_mem_free(pe_session->limAssocResponseData); + pe_session->limAssocResponseData = NULL; } - lim_restore_pre_reassoc_state(pMac, eSIR_SME_REASSOC_REFUSED, - reasonCode, psessionEntry); + lim_restore_pre_reassoc_state(mac_ctx, eSIR_SME_REASSOC_REFUSED, + rc, pe_session); return; } - lim_update_lost_link_info(pMac, psessionEntry, frame_rssi); - lim_post_sme_message(pMac, LIM_MLM_DISASSOC_IND, - (uint32_t *) &mlmDisassocInd); + lim_update_lost_link_info(mac_ctx, pe_session, frame_rssi); + lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_IND, + (uint32_t *) &mlmDisassocInd); /* send eWNI_SME_DISASSOC_IND to SME */ - lim_send_sme_disassoc_ind(pMac, pStaDs, psessionEntry); + lim_send_sme_disassoc_ind(mac_ctx, sta_ds, pe_session); return; -} /*** end lim_process_disassoc_frame() ***/ +} diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index 5f8077443c61..c3d94e30e6e3 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -471,7 +471,50 @@ void lim_send_mlm_assoc_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs, void lim_process_assoc_rsp_frame(tpAniSirGlobal, uint8_t *, uint8_t, tpPESession); void lim_process_disassoc_frame(tpAniSirGlobal, uint8_t *, tpPESession); +/* + * lim_perform_disassoc() - Actual action taken after receiving disassoc + * @mac_ctx: Global MAC context + * @frame_rssi: RSSI of the frame + * @rc: Reason code of the deauth + * @pe_session: PE session entry pointer + * @addr: BSSID from which the disassoc is received + * + * Return: None + */ +void lim_perform_disassoc(tpAniSirGlobal mac_ctx, int32_t frame_rssi, + uint16_t rc, tpPESession pe_session, + tSirMacAddr addr); +/* + * lim_disassoc_tdls_peers() - Disassoc action for tdls peers + * @mac_ctx: Global MAC context + * @pe_session: PE session entry pointer + * @addr: BSSID from which the disassoc is received + * + * Return: None + */ +#ifdef FEATURE_WLAN_TDLS +void lim_disassoc_tdls_peers(tpAniSirGlobal mac_ctx, + tpPESession pe_session, tSirMacAddr addr); +#else +void lim_disassoc_tdls_peers(tpAniSirGlobal mac_ctx, + tpPESession pe_session, tSirMacAddr addr) +{ + return; +} +#endif void lim_process_deauth_frame(tpAniSirGlobal, uint8_t *, tpPESession); +/* + * lim_perform_deauth() - Actual action taken after receiving deauth + * @mac_ctx: Global MAC context + * @pe_session: PE session entry pointer + * @rc: Reason code of the deauth + * @addr: BSSID from which the deauth is received + * @frame_rssi: RSSI of the frame + * + * Return: None + */ +void lim_perform_deauth(tpAniSirGlobal mac_ctx, tpPESession pe_session, + uint16_t rc, tSirMacAddr addr, int32_t frame_rssi); void lim_process_action_frame(tpAniSirGlobal, uint8_t *, tpPESession); void lim_process_action_frame_no_session(tpAniSirGlobal pMac, uint8_t *pRxMetaInfo); diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 599949d07897..d0a7fd0ae50d 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1731,7 +1731,8 @@ typedef struct { enum sir_roam_op_code reason); QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr); + tpSirBssDescription bss_desc_ptr, + enum sir_roam_op_code reason); qdf_wake_lock_t wmi_cmd_rsp_wake_lock; qdf_runtime_lock_t wmi_cmd_rsp_runtime_lock; qdf_runtime_lock_t wma_runtime_resume_lock; diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index c4f6141d8e4c..e51fa0cbf361 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -794,7 +794,8 @@ QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx, enum sir_roam_op_code reason), QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr)); + tpSirBssDescription bss_desc_ptr, + enum sir_roam_op_code reason)); #else static inline QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx, QDF_STATUS (*csr_roam_synch_cb)(tpAniSirGlobal mac, @@ -803,7 +804,8 @@ static inline QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx, enum sir_roam_op_code reason), QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr)) + tpSirBssDescription bss_desc_ptr, + enum sir_roam_op_code reason)) { return QDF_STATUS_E_NOSUPPORT; } diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 22b833533bdc..33c2bdc99f81 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -3791,7 +3791,8 @@ QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx, enum sir_roam_op_code reason), QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr)) + tpSirBssDescription bss_desc_ptr, + enum sir_roam_op_code reason)) { tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index fbe11b36b238..38e9e6fb1203 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -2929,7 +2929,8 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, qdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription) + ie_len); if (QDF_IS_STATUS_ERROR(wma->pe_roam_synch_cb( (tpAniSirGlobal)wma->mac_context, - roam_synch_ind_ptr, bss_desc_ptr))) { + roam_synch_ind_ptr, bss_desc_ptr, + SIR_ROAM_SYNCH_PROPAGATION))) { WMA_LOGE("LFR3: PE roam synch cb failed"); status = -EBUSY; goto cleanup_label; @@ -6601,6 +6602,9 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_ABORT) op_code = SIR_ROAMING_ABORT; roam_synch_data->roamedVdevId = wmi_event->vdev_id; + wma_handle->pe_roam_synch_cb( + (tpAniSirGlobal)wma_handle->mac_context, + roam_synch_data, NULL, op_code); wma_handle->csr_roam_synch_cb( (tpAniSirGlobal)wma_handle->mac_context, roam_synch_data, NULL, op_code); |
