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
This commit is contained in:
Varun Reddy Yeturu 2017-12-15 16:08:13 -08:00 • committed by snandini
commit b5d858ec80
10 changed files with 322 additions and 155 deletions

View file

@ -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.
*
@ -242,11 +242,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;
}

View file

@ -551,6 +551,10 @@ typedef struct sPESession /* Added to Support BT-AMP */
bool is_session_obss_offload_enabled;
bool is_obss_reset_timer_initialized;
bool sae_pmk_cached;
bool fw_roaming_started;
bool recvd_deauth_while_roaming;
bool recvd_disassoc_while_roaming;
bool deauth_disassoc_rc;
} tPESession, *tpPESession;
/*-------------------------------------------------------------------------

View file

@ -2080,6 +2080,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
@ -2089,7 +2090,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;
@ -2104,20 +2105,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.

View file

@ -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
@ -253,8 +250,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
@ -299,14 +318,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
@ -316,34 +351,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:
@ -353,102 +388,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);
"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 (psessionEntry->pLimMlmJoinReq) {
qdf_mem_free(psessionEntry->pLimMlmJoinReq);
psessionEntry->pLimMlmJoinReq = NULL;
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;
@ -460,7 +495,6 @@ lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
break;
default:
return;
} /* end switch (pMac->lim.gLimSystemRole) */
@ -468,30 +502,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;
/*
@ -500,18 +534,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");
@ -521,29 +555,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 (pMac->lim.deauthMsgCnt != 0) {
pMac->lim.deauthMsgCnt = 0;
* the deauth frame and sending up the indication as well */
if (mac_ctx->lim.deauthMsgCnt != 0) {
mac_ctx->lim.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() ***/
}

View file

@ -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
@ -203,13 +202,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
@ -287,20 +298,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?
@ -316,20 +314,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
@ -338,22 +381,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() ***/
}

View file

@ -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);

View file

@ -1531,7 +1531,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;
uint32_t fine_time_measurement_cap;

View file

@ -771,7 +771,8 @@ QDF_STATUS wma_register_roaming_callbacks(
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(
QDF_STATUS (*csr_roam_synch_cb)(tpAniSirGlobal mac,
@ -780,7 +781,8 @@ static inline QDF_STATUS wma_register_roaming_callbacks(
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;
}

View file

@ -3945,7 +3945,8 @@ QDF_STATUS wma_register_roaming_callbacks(
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);

View file

@ -2830,7 +2830,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;
@ -6138,6 +6139,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);