diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index 6cd8de9fc23c..2fd381ab4b74 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -818,6 +818,25 @@ lim_send_del_sta_cnf(tpAniSirGlobal pMac, struct qdf_mac_addr sta_dsaddr, smetransactionId); } + } else if (mlmStaContext.cleanupTrigger == eLIM_DUPLICATE_ENTRY) { + /** + * LIM driven Disassociation. + * Issue Disassoc Confirm to SME. + */ + lim_log(pMac, LOGW, + FL("Lim Posting DISASSOC_CNF to Sme. Trigger: %d"), + mlmStaContext.cleanupTrigger); + + qdf_mem_copy((uint8_t *) &mlmDisassocCnf.peerMacAddr, + (uint8_t *) sta_dsaddr.bytes, QDF_MAC_ADDR_SIZE); + mlmDisassocCnf.resultCode = statusCode; + mlmDisassocCnf.disassocTrigger = eLIM_DUPLICATE_ENTRY; + /* Update PE session Id */ + mlmDisassocCnf.sessionId = psessionEntry->peSessionId; + + lim_post_sme_message(pMac, + LIM_MLM_DISASSOC_CNF, + (uint32_t *) &mlmDisassocCnf); } if (NULL != psessionEntry && !LIM_IS_AP_ROLE(psessionEntry)) { diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index 85d6346bd05f..39a3c4855795 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -144,15 +144,16 @@ static void lim_convert_supported_channels(tpAniSirGlobal mac_ctx, * will be sent on that session and the STA deletion will happen. After this, * the ASSOC request will be processed * - * Return: void + * Return: True if duplicate entry found; FALSE otherwise. */ -void lim_check_sta_in_pe_entries(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr, +static bool lim_check_sta_in_pe_entries(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr, uint16_t sessionid) { uint8_t i; uint16_t assoc_id = 0; tpDphHashNode sta_ds = NULL; tpPESession session = NULL; + bool dup_entry = false; for (i = 0; i < mac_ctx->lim.maxBssId; i++) { if ((&mac_ctx->lim.gpSession[i] != NULL) && @@ -179,11 +180,18 @@ void lim_check_sta_in_pe_entries(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr, * msg to SME after delete sta which will update * the userspace with disconnect */ - lim_cleanup_rx_path(mac_ctx, sta_ds, session); + sta_ds->mlmStaContext.cleanupTrigger = + eLIM_DUPLICATE_ENTRY; + sta_ds->mlmStaContext.disassocReason = + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON; + lim_send_sme_disassoc_ind(mac_ctx, sta_ds, + session); + dup_entry = true; break; } } } + return dup_entry; } /** @@ -1718,6 +1726,7 @@ void lim_process_assoc_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, tSirMacCapabilityInfo local_cap; tpDphHashNode sta_ds = NULL; tpSirAssocReq assoc_req, tmp_assoc_req; + bool dup_entry = false; lim_get_phy_mode(mac_ctx, &phy_mode, session); @@ -1781,7 +1790,8 @@ void lim_process_assoc_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, return; } - lim_check_sta_in_pe_entries(mac_ctx, hdr, session->peSessionId); + dup_entry = lim_check_sta_in_pe_entries(mac_ctx, hdr, + session->peSessionId); /* Get pointer to Re/Association Request frame body */ frm_body = WMA_GET_RX_MPDU_DATA(rx_pkt_info); @@ -1963,9 +1973,12 @@ sendIndToSme: session->parsedAssocReq[sta_ds->assocId] = assoc_req; assoc_req_copied = true; - if (false == lim_update_sta_ctx(mac_ctx, session, assoc_req, + /* If it is duplicate entry wait till the peer is deleted */ + if (dup_entry != true) { + if (false == lim_update_sta_ctx(mac_ctx, session, assoc_req, sub_type, sta_ds, update_ctx)) goto error; + } /* AddSta is sucess here */ if (LIM_IS_AP_ROLE(session) && IS_DOT11_MODE_HT(session->dot11mode) && diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index 653ff560b02d..4fdd41270ddd 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -58,6 +58,7 @@ #include "cds_regdomain.h" #include "lim_send_messages.h" #include "nan_datapath.h" +#include "lim_assoc_utils.h" static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx, tpPESession session_entry, tSirResultCodes result_code, @@ -843,13 +844,51 @@ lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac, uint8_t *pBuf; tSirSmeDisassocRsp *pSirSmeDisassocRsp; tSirSmeDisassocInd *pSirSmeDisassocInd; - uint32_t *pMsg; + uint32_t *pMsg = NULL; bool failure = false; + tpPESession session = NULL; + uint16_t i, assoc_id; + tpDphHashNode sta_ds = NULL; lim_log(pMac, LOG1, FL("Disassoc Ntf with trigger : %d reasonCode: %d"), disassocTrigger, reasonCode); switch (disassocTrigger) { + case eLIM_DUPLICATE_ENTRY: + /* + * Duplicate entry is removed at LIM. + * Initiate new entry for other session + */ + lim_log(pMac, LOG1, + FL("Rcvd eLIM_DUPLICATE_ENTRY for " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(peerMacAddr)); + + for (i = 0; i < pMac->lim.maxBssId; i++) { + if ((&pMac->lim.gpSession[i] != NULL) && + (pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].pePersona == + QDF_SAP_MODE)) { + /* Find the sta ds entry in another session */ + session = &pMac->lim.gpSession[i]; + sta_ds = dph_lookup_hash_entry(pMac, + peerMacAddr, &assoc_id, + &session->dph.dphHashTable); + } + } + if (sta_ds +#ifdef WLAN_FEATURE_11W + && (!sta_ds->rmfEnabled) +#endif + ) { + if (lim_add_sta(pMac, sta_ds, false, session) != + eSIR_SUCCESS) + lim_log(pMac, LOGE, + FL("could not Add STA with assocId=%d"), + sta_ds->assocId); + } + failure = true; + break; + case eLIM_PEER_ENTITY_DISASSOC: if (reasonCode != eSIR_SME_STA_NOT_ASSOCIATED) { failure = true; diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index 41b5ab2b9cf1..571579dc4d87 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -158,7 +158,8 @@ enum eLimDisassocTrigger { eLIM_PEER_ENTITY_DEAUTH, eLIM_LINK_MONITORING_DEAUTH, eLIM_JOIN_FAILURE, - eLIM_REASSOC_REJECT + eLIM_REASSOC_REJECT, + eLIM_DUPLICATE_ENTRY }; /* Reason code to determine the channel change context while sending