|
@@ -0,0 +1,744 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
|
|
|
+ *
|
|
|
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
|
|
+ *
|
|
|
+ * Permission to use, copy, modify, and/or distribute this software for
|
|
|
+ * any purpose with or without fee is hereby granted, provided that the
|
|
|
+ * above copyright notice and this permission notice appear in all
|
|
|
+ * copies.
|
|
|
+ *
|
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
|
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
|
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|
|
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|
|
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
|
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
+ * PERFORMANCE OF THIS SOFTWARE.
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * DOC: lim_process_mlm_host_roam.c
|
|
|
+ *
|
|
|
+ * Host based roaming MLM implementation
|
|
|
+ */
|
|
|
+#include "cds_api.h"
|
|
|
+#include "wni_cfg.h"
|
|
|
+#include "ani_global.h"
|
|
|
+#include "sir_api.h"
|
|
|
+#include "sir_params.h"
|
|
|
+#include "cfg_api.h"
|
|
|
+
|
|
|
+#include "sch_api.h"
|
|
|
+#include "utils_api.h"
|
|
|
+#include "lim_utils.h"
|
|
|
+#include "lim_assoc_utils.h"
|
|
|
+#include "lim_prop_exts_utils.h"
|
|
|
+#include "lim_security_utils.h"
|
|
|
+#include "lim_send_messages.h"
|
|
|
+#include "lim_send_messages.h"
|
|
|
+#include "lim_session_utils.h"
|
|
|
+#include <lim_ft.h>
|
|
|
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
|
|
|
+#include "host_diag_core_log.h"
|
|
|
+#endif
|
|
|
+#include "wma_if.h"
|
|
|
+#include "rrm_api.h"
|
|
|
+static void lim_handle_sme_reaasoc_result(tpAniSirGlobal, tSirResultCodes,
|
|
|
+ uint16_t, tpPESession);
|
|
|
+/**
|
|
|
+ * lim_process_mlm_reassoc_req() - process mlm reassoc request.
|
|
|
+ *
|
|
|
+ * @mac_ctx: pointer to Global MAC structure
|
|
|
+ * @msg: pointer to the MLM message buffer
|
|
|
+ *
|
|
|
+ * This function is called to process MLM_REASSOC_REQ message
|
|
|
+ * from SME
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+void lim_process_mlm_reassoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg)
|
|
|
+{
|
|
|
+ uint8_t channel, sec_ch_offset;
|
|
|
+ struct tLimPreAuthNode *auth_node;
|
|
|
+ tLimMlmReassocReq *reassoc_req;
|
|
|
+ tLimMlmReassocCnf reassoc_cnf;
|
|
|
+ tpPESession session;
|
|
|
+
|
|
|
+ if (msg == NULL) {
|
|
|
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ reassoc_req = (tLimMlmReassocReq *) msg;
|
|
|
+ session = pe_find_session_by_session_id(mac_ctx,
|
|
|
+ reassoc_req->sessionId);
|
|
|
+ if (NULL == session) {
|
|
|
+ lim_log(mac_ctx, LOGE,
|
|
|
+ FL("Session Does not exist for given sessionId %d"),
|
|
|
+ reassoc_req->sessionId);
|
|
|
+ qdf_mem_free(reassoc_req);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ lim_log(mac_ctx, LOG1,
|
|
|
+ FL("ReAssoc Req on session %d role %d mlm %d " MAC_ADDRESS_STR),
|
|
|
+ reassoc_req->sessionId, GET_LIM_SYSTEM_ROLE(session),
|
|
|
+ session->limMlmState, MAC_ADDR_ARRAY(reassoc_req->peerMacAddr));
|
|
|
+
|
|
|
+ if ((LIM_IS_AP_ROLE(session) ||
|
|
|
+ LIM_IS_BT_AMP_AP_ROLE(session)) ||
|
|
|
+ (session->limMlmState !=
|
|
|
+ eLIM_MLM_LINK_ESTABLISHED_STATE)) {
|
|
|
+ /*
|
|
|
+ * Received Reassoc request in invalid state or
|
|
|
+ * in AP role.Return Reassoc confirm with Invalid
|
|
|
+ * parameters code.
|
|
|
+ */
|
|
|
+
|
|
|
+ lim_log(mac_ctx, LOGW,
|
|
|
+ FL("unexpect msg,state %Xrole %d,MAC" MAC_ADDRESS_STR),
|
|
|
+ session->limMlmState, GET_LIM_SYSTEM_ROLE(session),
|
|
|
+ MAC_ADDR_ARRAY(reassoc_req->peerMacAddr));
|
|
|
+ lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
|
|
|
+ reassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
|
|
|
+ reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (session->pLimMlmReassocReq)
|
|
|
+ qdf_mem_free(session->pLimMlmReassocReq);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Hold Re-Assoc request as part of Session, knock-out mac_ctx
|
|
|
+ * Hold onto Reassoc request parameters
|
|
|
+ */
|
|
|
+ session->pLimMlmReassocReq = reassoc_req;
|
|
|
+
|
|
|
+ /* See if we have pre-auth context with new AP */
|
|
|
+ auth_node = lim_search_pre_auth_list(mac_ctx, session->limReAssocbssId);
|
|
|
+
|
|
|
+ if (!auth_node && (qdf_mem_cmp(reassoc_req->peerMacAddr,
|
|
|
+ session->bssId,
|
|
|
+ sizeof(tSirMacAddr)))) {
|
|
|
+ /*
|
|
|
+ * Either pre-auth context does not exist AND
|
|
|
+ * we are not reassociating with currently
|
|
|
+ * associated AP.
|
|
|
+ * Return Reassoc confirm with not authenticated
|
|
|
+ */
|
|
|
+ reassoc_cnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED;
|
|
|
+ reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
|
|
|
+
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ /* assign the sessionId to the timer object */
|
|
|
+ mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId =
|
|
|
+ reassoc_req->sessionId;
|
|
|
+ session->limPrevMlmState = session->limMlmState;
|
|
|
+ session->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
|
|
|
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
|
|
|
+ session->limMlmState));
|
|
|
+
|
|
|
+ /* Derive channel from BSS description and store it at CFG. */
|
|
|
+ channel = session->limReassocChannelId;
|
|
|
+ sec_ch_offset = session->reAssocHtSecondaryChannelOffset;
|
|
|
+
|
|
|
+ /* Apply previously set configuration at HW */
|
|
|
+ lim_apply_configuration(mac_ctx, session);
|
|
|
+
|
|
|
+ /* store the channel switch sessionEntry in the lim global var */
|
|
|
+ session->channelChangeReasonCode =
|
|
|
+ LIM_SWITCH_CHANNEL_REASSOC;
|
|
|
+
|
|
|
+ /* Switch channel to the new Operating channel for Reassoc */
|
|
|
+ lim_set_channel(mac_ctx, channel,
|
|
|
+ session->ch_center_freq_seg0,
|
|
|
+ session->ch_center_freq_seg1,
|
|
|
+ session->ch_width,
|
|
|
+ session->maxTxPower,
|
|
|
+ session->peSessionId);
|
|
|
+
|
|
|
+ return;
|
|
|
+end:
|
|
|
+ reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
|
|
|
+ /* Update PE sessio Id */
|
|
|
+ reassoc_cnf.sessionId = reassoc_req->sessionId;
|
|
|
+ /* Free up buffer allocated for reassocReq */
|
|
|
+ qdf_mem_free(reassoc_req);
|
|
|
+ session->pLimReAssocReq = NULL;
|
|
|
+ lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
|
|
|
+ (uint32_t *) &reassoc_cnf);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * lim_handle_sme_reaasoc_result() - Handle the reassoc result
|
|
|
+ * @pMac: Global MAC Context
|
|
|
+ * @resultCode: Result code
|
|
|
+ * @protStatusCode: Protocol Status Code
|
|
|
+ * @psessionEntry: PE Session
|
|
|
+ *
|
|
|
+ * This function is called to process reassoc failures
|
|
|
+ * upon receiving REASSOC_CNF with a failure code or
|
|
|
+ * MLM_REASSOC_CNF with a success code in case of STA role
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+static void lim_handle_sme_reaasoc_result(tpAniSirGlobal pMac,
|
|
|
+ tSirResultCodes resultCode, uint16_t protStatusCode,
|
|
|
+ tpPESession psessionEntry)
|
|
|
+{
|
|
|
+ tpDphHashNode pStaDs = NULL;
|
|
|
+ uint8_t smesessionId;
|
|
|
+ uint16_t smetransactionId;
|
|
|
+
|
|
|
+ if (psessionEntry == NULL) {
|
|
|
+ PELOGE(lim_log(pMac, LOGE, FL("psessionEntry is NULL "));)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ smesessionId = psessionEntry->smeSessionId;
|
|
|
+ smetransactionId = psessionEntry->transactionId;
|
|
|
+ if (resultCode != eSIR_SME_SUCCESS) {
|
|
|
+ pStaDs =
|
|
|
+ dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
|
|
|
+ &psessionEntry->dph.dphHashTable);
|
|
|
+ if (pStaDs != NULL) {
|
|
|
+ pStaDs->mlmStaContext.disassocReason =
|
|
|
+ eSIR_MAC_UNSPEC_FAILURE_REASON;
|
|
|
+ pStaDs->mlmStaContext.cleanupTrigger =
|
|
|
+ eLIM_JOIN_FAILURE;
|
|
|
+ pStaDs->mlmStaContext.resultCode = resultCode;
|
|
|
+ pStaDs->mlmStaContext.protStatusCode = protStatusCode;
|
|
|
+ lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
|
|
|
+ /* Cleanup if add bss failed */
|
|
|
+ if (psessionEntry->add_bss_failed) {
|
|
|
+ dph_delete_hash_entry(pMac,
|
|
|
+ pStaDs->staAddr, pStaDs->assocId,
|
|
|
+ &psessionEntry->dph.dphHashTable);
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+error:
|
|
|
+ /* Delete teh session if REASSOC failure occurred. */
|
|
|
+ if (resultCode != eSIR_SME_SUCCESS) {
|
|
|
+ if (NULL != psessionEntry) {
|
|
|
+ pe_delete_session(pMac, psessionEntry);
|
|
|
+ psessionEntry = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_REASSOC_RSP, resultCode,
|
|
|
+ protStatusCode, psessionEntry, smesessionId, smetransactionId);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * lim_process_mlm_reassoc_cnf() - process mlm reassoc cnf msg
|
|
|
+ *
|
|
|
+ * @mac_ctx: Pointer to Global MAC structure
|
|
|
+ * @msg_buf: A pointer to the MLM message buffer
|
|
|
+ *
|
|
|
+ * This function is called to process MLM_REASSOC_CNF message from MLM State
|
|
|
+ * machine.
|
|
|
+ *
|
|
|
+ * @Return: void
|
|
|
+ */
|
|
|
+void lim_process_mlm_reassoc_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
|
|
|
+{
|
|
|
+ tpPESession session;
|
|
|
+ tLimMlmReassocCnf *lim_mlm_reassoc_cnf;
|
|
|
+
|
|
|
+ if (msg_buf == NULL) {
|
|
|
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ lim_mlm_reassoc_cnf = (tLimMlmReassocCnf *) msg_buf;
|
|
|
+ session = pe_find_session_by_session_id(mac_ctx,
|
|
|
+ lim_mlm_reassoc_cnf->sessionId);
|
|
|
+ if (session == NULL) {
|
|
|
+ lim_log(mac_ctx, LOGE,
|
|
|
+ FL("session Does not exist for given session Id"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ((session->limSmeState != eLIM_SME_WT_REASSOC_STATE) ||
|
|
|
+ LIM_IS_AP_ROLE(session) || LIM_IS_BT_AMP_AP_ROLE(session)) {
|
|
|
+ /*
|
|
|
+ * Should not have received Reassocication confirm
|
|
|
+ * from MLM in other states OR on AP.
|
|
|
+ */
|
|
|
+ lim_log(mac_ctx, LOGE,
|
|
|
+ FL("Rcv unexpected MLM_REASSOC_CNF role %d, sme 0x%X"),
|
|
|
+ GET_LIM_SYSTEM_ROLE(session), session->limSmeState);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (session->pLimReAssocReq) {
|
|
|
+ qdf_mem_free(session->pLimReAssocReq);
|
|
|
+ session->pLimReAssocReq = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Upon Reassoc success or failure, freeup the cached preauth request,
|
|
|
+ * to ensure that channel switch is now allowed following any change in
|
|
|
+ * HT params.
|
|
|
+ */
|
|
|
+ if (session->ftPEContext.pFTPreAuthReq) {
|
|
|
+ lim_log(mac_ctx, LOG1, FL("Freeing pFTPreAuthReq= %p"),
|
|
|
+ session->ftPEContext.pFTPreAuthReq);
|
|
|
+ if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
|
|
|
+ qdf_mem_free(
|
|
|
+ session->ftPEContext.pFTPreAuthReq->pbssDescription);
|
|
|
+ session->ftPEContext.pFTPreAuthReq->pbssDescription =
|
|
|
+ NULL;
|
|
|
+ }
|
|
|
+ qdf_mem_free(session->ftPEContext.pFTPreAuthReq);
|
|
|
+ session->ftPEContext.pFTPreAuthReq = NULL;
|
|
|
+ session->ftPEContext.ftPreAuthSession = false;
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
|
|
+ if (session->bRoamSynchInProgress) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("LFR3:Re-set the LIM Ctxt Roam Synch In Progress"));
|
|
|
+ session->bRoamSynchInProgress = false;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ lim_log(mac_ctx, LOG1, FL("Rcv MLM_REASSOC_CNF with result code %d"),
|
|
|
+ lim_mlm_reassoc_cnf->resultCode);
|
|
|
+ if (lim_mlm_reassoc_cnf->resultCode == eSIR_SME_SUCCESS) {
|
|
|
+ /* Successful Reassociation */
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("*** Reassociated with new BSS ***"));
|
|
|
+
|
|
|
+ session->limSmeState = eLIM_SME_LINK_EST_STATE;
|
|
|
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
|
|
|
+ session->peSessionId, session->limSmeState));
|
|
|
+
|
|
|
+ /* Need to send Reassoc rsp with Reassoc success to Host. */
|
|
|
+ lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
|
|
|
+ lim_mlm_reassoc_cnf->resultCode,
|
|
|
+ lim_mlm_reassoc_cnf->protStatusCode,
|
|
|
+ session, session->smeSessionId,
|
|
|
+ session->transactionId);
|
|
|
+ } else if (lim_mlm_reassoc_cnf->resultCode
|
|
|
+ == eSIR_SME_REASSOC_REFUSED) {
|
|
|
+ /*
|
|
|
+ * Reassociation failure With the New AP but we still have the
|
|
|
+ * link with the Older AP
|
|
|
+ */
|
|
|
+ session->limSmeState = eLIM_SME_LINK_EST_STATE;
|
|
|
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
|
|
|
+ session->peSessionId, session->limSmeState));
|
|
|
+
|
|
|
+ /* Need to send Reassoc rsp with Assoc failure to Host. */
|
|
|
+ lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
|
|
|
+ lim_mlm_reassoc_cnf->resultCode,
|
|
|
+ lim_mlm_reassoc_cnf->protStatusCode,
|
|
|
+ session, session->smeSessionId,
|
|
|
+ session->transactionId);
|
|
|
+ } else {
|
|
|
+ /* Reassociation failure */
|
|
|
+ session->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
|
|
|
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
|
|
|
+ session->peSessionId, session->limSmeState));
|
|
|
+ /* Need to send Reassoc rsp with Assoc failure to Host. */
|
|
|
+ lim_handle_sme_reaasoc_result(mac_ctx,
|
|
|
+ lim_mlm_reassoc_cnf->resultCode,
|
|
|
+ lim_mlm_reassoc_cnf->protStatusCode,
|
|
|
+ session);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * lim_process_sta_mlm_add_bss_rsp_ft() - Handle the ADD BSS response
|
|
|
+ * @pMac: Global MAC context
|
|
|
+ * @limMsgQ: ADD BSS Parameters
|
|
|
+ * @psessionEntry: PE Session
|
|
|
+ *
|
|
|
+ * Function to handle WMA_ADD_BSS_RSP, in FT reassoc state.
|
|
|
+ * Send ReAssociation Request.
|
|
|
+ *
|
|
|
+ *Return: None
|
|
|
+ */
|
|
|
+void lim_process_sta_mlm_add_bss_rsp_ft(tpAniSirGlobal pMac,
|
|
|
+ tpSirMsgQ limMsgQ, tpPESession psessionEntry)
|
|
|
+{
|
|
|
+ tLimMlmReassocCnf mlmReassocCnf; /* keep sme */
|
|
|
+ tpDphHashNode pStaDs = NULL;
|
|
|
+ tpAddStaParams pAddStaParams = NULL;
|
|
|
+ uint32_t listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
|
|
|
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
|
|
|
+ uint32_t selfStaDot11Mode = 0;
|
|
|
+
|
|
|
+ /* Sanity Checks */
|
|
|
+
|
|
|
+ if (pAddBssParams == NULL) {
|
|
|
+ PELOGE(lim_log(pMac, LOGE, FL("Invalid parameters"));)
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE !=
|
|
|
+ psessionEntry->limMlmState) {
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ pStaDs = dph_add_hash_entry(pMac, pAddBssParams->bssId,
|
|
|
+ DPH_STA_HASH_INDEX_PEER,
|
|
|
+ &psessionEntry->dph.dphHashTable);
|
|
|
+ if (pStaDs == NULL) {
|
|
|
+ /* Could not add hash table entry */
|
|
|
+ lim_log(pMac, LOGE, FL("could not add hash entry at DPH for"));
|
|
|
+ lim_print_mac_addr(pMac, pAddBssParams->staContext.staMac,
|
|
|
+ LOGE);
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ /* Prepare and send Reassociation request frame */
|
|
|
+ /* start reassoc timer. */
|
|
|
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
|
|
+ if (psessionEntry->bRoamSynchInProgress != true) {
|
|
|
+#endif
|
|
|
+ pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
|
|
|
+ psessionEntry->peSessionId;
|
|
|
+ /* / Start reassociation failure timer */
|
|
|
+ MTRACE(mac_trace
|
|
|
+ (pMac, TRACE_CODE_TIMER_ACTIVATE,
|
|
|
+ psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
|
|
|
+ if (tx_timer_activate
|
|
|
+ (&pMac->lim.limTimers.gLimReassocFailureTimer)
|
|
|
+ != TX_SUCCESS) {
|
|
|
+ /* / Could not start reassoc failure timer. */
|
|
|
+ /* Log error */
|
|
|
+ lim_log(pMac, LOGP,
|
|
|
+ FL("could not start Reassoc failure timer"));
|
|
|
+ /* Return Reassoc confirm with */
|
|
|
+ /* Resources Unavailable */
|
|
|
+ mlmReassocCnf.resultCode =
|
|
|
+ eSIR_SME_RESOURCES_UNAVAILABLE;
|
|
|
+ mlmReassocCnf.protStatusCode =
|
|
|
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ pMac->lim.pSessionEntry = psessionEntry;
|
|
|
+ if (NULL == pMac->lim.pSessionEntry->pLimMlmReassocRetryReq) {
|
|
|
+ /* Take a copy of reassoc request for retrying */
|
|
|
+ pMac->lim.pSessionEntry->pLimMlmReassocRetryReq =
|
|
|
+ qdf_mem_malloc(sizeof(tLimMlmReassocReq));
|
|
|
+ if (NULL ==
|
|
|
+ pMac->lim.pSessionEntry->pLimMlmReassocRetryReq)
|
|
|
+ goto end;
|
|
|
+ qdf_mem_set(pMac->lim.pSessionEntry->
|
|
|
+ pLimMlmReassocRetryReq,
|
|
|
+ sizeof(tLimMlmReassocReq), 0);
|
|
|
+ qdf_mem_copy(pMac->lim.pSessionEntry->
|
|
|
+ pLimMlmReassocRetryReq,
|
|
|
+ psessionEntry->pLimMlmReassocReq,
|
|
|
+ sizeof(tLimMlmReassocReq));
|
|
|
+ }
|
|
|
+ pMac->lim.reAssocRetryAttempt = 0;
|
|
|
+ lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac,
|
|
|
+ psessionEntry->
|
|
|
+ pLimMlmReassocReq,
|
|
|
+ psessionEntry);
|
|
|
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
|
|
+ } else {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ "LFR3:Do not activate timer and dont send the reassoc");
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
|
|
|
+ psessionEntry->limMlmState = eLIM_MLM_WT_FT_REASSOC_RSP_STATE;
|
|
|
+ MTRACE(mac_trace
|
|
|
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
|
|
|
+ eLIM_MLM_WT_FT_REASSOC_RSP_STATE));
|
|
|
+ PELOGE(lim_log
|
|
|
+ (pMac, LOG1, FL("Set the mlm state to %d session=%d"),
|
|
|
+ psessionEntry->limMlmState, psessionEntry->peSessionId);
|
|
|
+ )
|
|
|
+
|
|
|
+ psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
|
|
|
+
|
|
|
+ /* Success, handle below */
|
|
|
+ pStaDs->bssId = pAddBssParams->bssIdx;
|
|
|
+ /* STA Index(genr by HAL) for the BSS entry is stored here */
|
|
|
+ pStaDs->staIndex = pAddBssParams->staContext.staIdx;
|
|
|
+ pStaDs->ucUcastSig = pAddBssParams->staContext.ucUcastSig;
|
|
|
+ pStaDs->ucBcastSig = pAddBssParams->staContext.ucBcastSig;
|
|
|
+
|
|
|
+ rrm_cache_mgmt_tx_power(pMac, pAddBssParams->txMgmtPower,
|
|
|
+ psessionEntry);
|
|
|
+
|
|
|
+ pAddStaParams = qdf_mem_malloc(sizeof(tAddStaParams));
|
|
|
+ if (NULL == pAddStaParams) {
|
|
|
+ lim_log(pMac, LOGP,
|
|
|
+ FL("Unable to allocate memory during ADD_STA"));
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+ qdf_mem_set((uint8_t *) pAddStaParams, sizeof(tAddStaParams), 0);
|
|
|
+
|
|
|
+ /* / Add STA context at MAC HW (BMU, RHP & TFP) */
|
|
|
+ qdf_mem_copy((uint8_t *) pAddStaParams->staMac,
|
|
|
+ (uint8_t *) psessionEntry->selfMacAddr,
|
|
|
+ sizeof(tSirMacAddr));
|
|
|
+
|
|
|
+ qdf_mem_copy((uint8_t *) pAddStaParams->bssId,
|
|
|
+ psessionEntry->bssId, sizeof(tSirMacAddr));
|
|
|
+
|
|
|
+ pAddStaParams->staType = STA_ENTRY_SELF;
|
|
|
+ pAddStaParams->status = QDF_STATUS_SUCCESS;
|
|
|
+ pAddStaParams->respReqd = 1;
|
|
|
+
|
|
|
+ /* Update PE session ID */
|
|
|
+ pAddStaParams->sessionId = psessionEntry->peSessionId;
|
|
|
+ pAddStaParams->smesessionId = psessionEntry->smeSessionId;
|
|
|
+
|
|
|
+ /* This will indicate HAL to "allocate" a new STA index */
|
|
|
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
|
|
+ if (psessionEntry->bRoamSynchInProgress != true)
|
|
|
+#endif
|
|
|
+ pAddStaParams->staIdx = STA_INVALID_IDX;
|
|
|
+ pAddStaParams->updateSta = false;
|
|
|
+
|
|
|
+ pAddStaParams->shortPreambleSupported =
|
|
|
+ (uint8_t) psessionEntry->beaconParams.fShortPreamble;
|
|
|
+ lim_populate_peer_rate_set(pMac, &pAddStaParams->supportedRates, NULL,
|
|
|
+ false, psessionEntry, NULL);
|
|
|
+
|
|
|
+ if (psessionEntry->htCapability) {
|
|
|
+ pAddStaParams->htCapable = psessionEntry->htCapability;
|
|
|
+ pAddStaParams->vhtCapable = psessionEntry->vhtCapability;
|
|
|
+ pAddStaParams->ch_width = psessionEntry->ch_width;
|
|
|
+ pAddStaParams->greenFieldCapable =
|
|
|
+ lim_get_ht_capability(pMac, eHT_GREENFIELD,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->mimoPS =
|
|
|
+ lim_get_ht_capability(pMac, eHT_MIMO_POWER_SAVE,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->rifsMode =
|
|
|
+ lim_get_ht_capability(pMac, eHT_RIFS_MODE,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->lsigTxopProtection =
|
|
|
+ lim_get_ht_capability(pMac, eHT_LSIG_TXOP_PROTECTION,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->maxAmpduDensity =
|
|
|
+ lim_get_ht_capability(pMac, eHT_MPDU_DENSITY,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->maxAmpduSize =
|
|
|
+ lim_get_ht_capability(pMac, eHT_MAX_RX_AMPDU_FACTOR,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->maxAmsduSize =
|
|
|
+ lim_get_ht_capability(pMac, eHT_MAX_AMSDU_LENGTH,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->fDsssCckMode40Mhz =
|
|
|
+ lim_get_ht_capability(pMac, eHT_DSSS_CCK_MODE_40MHZ,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->fShortGI20Mhz =
|
|
|
+ lim_get_ht_capability(pMac, eHT_SHORT_GI_20MHZ,
|
|
|
+ psessionEntry);
|
|
|
+ pAddStaParams->fShortGI40Mhz =
|
|
|
+ lim_get_ht_capability(pMac, eHT_SHORT_GI_40MHZ,
|
|
|
+ psessionEntry);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (wlan_cfg_get_int(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) !=
|
|
|
+ eSIR_SUCCESS)
|
|
|
+ lim_log(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL"));
|
|
|
+ pAddStaParams->listenInterval = (uint16_t) listenInterval;
|
|
|
+
|
|
|
+ wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
|
|
|
+ pAddStaParams->encryptType = psessionEntry->encryptType;
|
|
|
+ pAddStaParams->maxTxPower = psessionEntry->maxTxPower;
|
|
|
+
|
|
|
+ /* Lets save this for when we receive the Reassoc Rsp */
|
|
|
+ psessionEntry->ftPEContext.pAddStaReq = pAddStaParams;
|
|
|
+
|
|
|
+ if (pAddBssParams != NULL) {
|
|
|
+ qdf_mem_free(pAddBssParams);
|
|
|
+ pAddBssParams = NULL;
|
|
|
+ limMsgQ->bodyptr = NULL;
|
|
|
+ }
|
|
|
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
|
|
+ if (psessionEntry->bRoamSynchInProgress) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ "LFR3:Prep and save AddStaReq for post-assoc-rsp");
|
|
|
+ lim_process_assoc_rsp_frame(pMac, pMac->roam.pReassocResp,
|
|
|
+ LIM_REASSOC, psessionEntry);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ return;
|
|
|
+
|
|
|
+end:
|
|
|
+ /* Free up buffer allocated for reassocReq */
|
|
|
+ if (psessionEntry != NULL)
|
|
|
+ if (psessionEntry->pLimMlmReassocReq != NULL) {
|
|
|
+ qdf_mem_free(psessionEntry->pLimMlmReassocReq);
|
|
|
+ psessionEntry->pLimMlmReassocReq = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pAddBssParams != NULL) {
|
|
|
+ qdf_mem_free(pAddBssParams);
|
|
|
+ pAddBssParams = NULL;
|
|
|
+ limMsgQ->bodyptr = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
|
|
|
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
|
|
|
+ /* Update PE session Id */
|
|
|
+ if (psessionEntry != NULL)
|
|
|
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
|
|
|
+ else
|
|
|
+ mlmReassocCnf.sessionId = 0;
|
|
|
+
|
|
|
+ lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
|
|
|
+ (uint32_t *) &mlmReassocCnf);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * lim_process_mlm_ft_reassoc_req() - Handle the Reassoc request
|
|
|
+ * @pMac: Global MAC context
|
|
|
+ * @pMsgBuf: Buffer which holds the data
|
|
|
+ * @psessionEntry: PE Session
|
|
|
+ *
|
|
|
+ * This function handles the Reassoc Req from SME
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf,
|
|
|
+ tpPESession psessionEntry)
|
|
|
+{
|
|
|
+ uint8_t smeSessionId = 0;
|
|
|
+ uint16_t transactionId = 0;
|
|
|
+ uint8_t chanNum = 0;
|
|
|
+ tLimMlmReassocReq *pMlmReassocReq;
|
|
|
+ uint16_t caps;
|
|
|
+ uint32_t val;
|
|
|
+ tSirMsgQ msgQ;
|
|
|
+ tSirRetStatus retCode;
|
|
|
+ uint32_t teleBcnEn = 0;
|
|
|
+
|
|
|
+ chanNum = psessionEntry->currentOperChannel;
|
|
|
+ lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smeSessionId,
|
|
|
+ &transactionId);
|
|
|
+ psessionEntry->smeSessionId = smeSessionId;
|
|
|
+ psessionEntry->transactionId = transactionId;
|
|
|
+
|
|
|
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
|
|
|
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOCIATING,
|
|
|
+ psessionEntry, 0, 0);
|
|
|
+#endif
|
|
|
+
|
|
|
+ /* Nothing to be done if the session is not in STA mode */
|
|
|
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
|
|
|
+ lim_log(pMac, LOGE, FL("psessionEntry is not in STA mode"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (NULL == psessionEntry->ftPEContext.pAddBssReq) {
|
|
|
+ lim_log(pMac, LOGE, FL("pAddBssReq is NULL"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pMlmReassocReq = qdf_mem_malloc(sizeof(tLimMlmReassocReq));
|
|
|
+ if (NULL == pMlmReassocReq) {
|
|
|
+ lim_log(pMac, LOGE,
|
|
|
+ FL("call to AllocateMemory failed for mlmReassocReq"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_mem_copy(pMlmReassocReq->peerMacAddr,
|
|
|
+ psessionEntry->bssId, sizeof(tSirMacAddr));
|
|
|
+
|
|
|
+ if (wlan_cfg_get_int(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
|
|
|
+ (uint32_t *) &pMlmReassocReq->reassocFailureTimeout)
|
|
|
+ != eSIR_SUCCESS) {
|
|
|
+ /**
|
|
|
+ * Could not get ReassocFailureTimeout value
|
|
|
+ * from CFG. Log error.
|
|
|
+ */
|
|
|
+ lim_log(pMac, LOGE,
|
|
|
+ FL("could not retrieve ReassocFailureTimeout value"));
|
|
|
+ qdf_mem_free(pMlmReassocReq);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cfg_get_capability_info(pMac, &caps, psessionEntry) !=
|
|
|
+ eSIR_SUCCESS) {
|
|
|
+ /**
|
|
|
+ * Could not get Capabilities value
|
|
|
+ * from CFG. Log error.
|
|
|
+ */
|
|
|
+ lim_log(pMac, LOGE, FL("could not get Capabilities value"));
|
|
|
+ qdf_mem_free(pMlmReassocReq);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pMlmReassocReq->capabilityInfo = caps;
|
|
|
+
|
|
|
+ /* Update PE sessionId */
|
|
|
+ pMlmReassocReq->sessionId = psessionEntry->peSessionId;
|
|
|
+
|
|
|
+ /* If telescopic beaconing is enabled, set listen interval
|
|
|
+ to WNI_CFG_TELE_BCN_MAX_LI
|
|
|
+ */
|
|
|
+ if (wlan_cfg_get_int(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) !=
|
|
|
+ eSIR_SUCCESS) {
|
|
|
+ lim_log(pMac, LOGP,
|
|
|
+ FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN"));
|
|
|
+ qdf_mem_free(pMlmReassocReq);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (teleBcnEn) {
|
|
|
+ if (wlan_cfg_get_int(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
|
|
|
+ eSIR_SUCCESS) {
|
|
|
+ /**
|
|
|
+ * Could not get ListenInterval value
|
|
|
+ * from CFG. Log error.
|
|
|
+ */
|
|
|
+ lim_log(pMac, LOGE,
|
|
|
+ FL("could not retrieve ListenInterval"));
|
|
|
+ qdf_mem_free(pMlmReassocReq);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (wlan_cfg_get_int(pMac, WNI_CFG_LISTEN_INTERVAL, &val) !=
|
|
|
+ eSIR_SUCCESS) {
|
|
|
+ /**
|
|
|
+ * Could not get ListenInterval value
|
|
|
+ * from CFG. Log error.
|
|
|
+ */
|
|
|
+ lim_log(pMac, LOGE,
|
|
|
+ FL("could not retrieve ListenInterval"));
|
|
|
+ qdf_mem_free(pMlmReassocReq);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (lim_set_link_state
|
|
|
+ (pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
|
|
|
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) {
|
|
|
+ qdf_mem_free(pMlmReassocReq);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ pMlmReassocReq->listenInterval = (uint16_t) val;
|
|
|
+ psessionEntry->pLimMlmReassocReq = pMlmReassocReq;
|
|
|
+
|
|
|
+ /* we need to defer the message until we get response back from HAL */
|
|
|
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
|
|
|
+
|
|
|
+ msgQ.type = SIR_HAL_ADD_BSS_REQ;
|
|
|
+ msgQ.reserved = 0;
|
|
|
+ msgQ.bodyptr = psessionEntry->ftPEContext.pAddBssReq;
|
|
|
+ msgQ.bodyval = 0;
|
|
|
+
|
|
|
+ lim_log(pMac, LOG1, FL("Sending SIR_HAL_ADD_BSS_REQ..."));
|
|
|
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
|
|
|
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
|
|
|
+ if (eSIR_SUCCESS != retCode) {
|
|
|
+ qdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
|
|
|
+ lim_log(pMac, LOGE,
|
|
|
+ FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
|
|
|
+ retCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ psessionEntry->ftPEContext.pAddBssReq = NULL;
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|