summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Reddy Yeturu <varunreddy.yeturu@codeaurora.org>2017-12-15 16:08:13 -0800
committersnandini <snandini@codeaurora.org>2018-02-20 14:37:53 -0800
commit3bc1d1cbcb2d47ab8391af6ff4a5e78707ca789f (patch)
treecbb5ba1a42f32fff6b17d5be4a5684dd24b66538
parente70bbd09e6e13bd6e69ec98520df003317d97bcf (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.h6
-rw-r--r--core/mac/src/pe/include/lim_session.h4
-rw-r--r--core/mac/src/pe/lim/lim_api.c45
-rw-r--r--core/mac/src/pe/lim/lim_process_deauth_frame.c250
-rw-r--r--core/mac/src/pe/lim/lim_process_disassoc_frame.c109
-rw-r--r--core/mac/src/pe/lim/lim_types.h43
-rw-r--r--core/wma/inc/wma.h3
-rw-r--r--core/wma/inc/wma_types.h6
-rw-r--r--core/wma/src/wma_mgmt.c3
-rw-r--r--core/wma/src/wma_scan_roam.c6
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);