blob: 44374ba1c3dbb86d1580cd676039ea89db8e9393 [file] [log] [blame]
/*
* Copyright (c) 2012-2017 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
#include "wni_api.h"
#include "wni_cfg.h"
#include "cfg_api.h"
#include "sir_api.h"
#include "sch_api.h"
#include "utils_api.h"
#include "lim_utils.h"
#include "lim_assoc_utils.h"
#include "lim_security_utils.h"
#include "lim_ser_des_utils.h"
#include "lim_timer_utils.h"
#include "lim_send_messages.h"
#include "lim_admit_control.h"
#include "lim_send_messages.h"
#include "lim_ibss_peer_mgmt.h"
#include "lim_ft.h"
#include "lim_ft_defs.h"
#include "lim_session.h"
#include "lim_session_utils.h"
#include "rrm_api.h"
#include "wma_types.h"
#include "cds_utils.h"
#include "lim_types.h"
#include "cds_concurrency.h"
#include "nan_datapath.h"
#define MAX_SUPPORTED_PEERS_WEP 16
void lim_process_mlm_join_cnf(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_auth_cnf(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_start_cnf(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_assoc_ind(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_assoc_cnf(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_reassoc_ind(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_set_keys_cnf(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_disassoc_ind(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_disassoc_cnf(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_deauth_ind(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_deauth_cnf(tpAniSirGlobal, uint32_t *);
void lim_process_mlm_purge_sta_ind(tpAniSirGlobal, uint32_t *);
void lim_get_session_info(tpAniSirGlobal pMac, uint8_t *, uint8_t *,
uint16_t *);
/**
* lim_process_mlm_rsp_messages()
*
***FUNCTION:
* This function is called to processes various MLM response (CNF/IND
* messages from MLM State machine.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param msgType Indicates the MLM message type
* @param *pMsgBuf A pointer to the MLM message buffer
*
* @return None
*/
void
lim_process_mlm_rsp_messages(tpAniSirGlobal pMac, uint32_t msgType,
uint32_t *pMsgBuf)
{
if (pMsgBuf == NULL) {
PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
return;
}
MTRACE(mac_trace(pMac, TRACE_CODE_TX_LIM_MSG, 0, msgType));
switch (msgType) {
case LIM_MLM_AUTH_CNF:
lim_process_mlm_auth_cnf(pMac, pMsgBuf);
break;
case LIM_MLM_ASSOC_CNF:
lim_process_mlm_assoc_cnf(pMac, pMsgBuf);
break;
case LIM_MLM_START_CNF:
lim_process_mlm_start_cnf(pMac, pMsgBuf);
break;
case LIM_MLM_JOIN_CNF:
lim_process_mlm_join_cnf(pMac, pMsgBuf);
break;
case LIM_MLM_ASSOC_IND:
lim_process_mlm_assoc_ind(pMac, pMsgBuf);
break;
case LIM_MLM_REASSOC_CNF:
lim_process_mlm_reassoc_cnf(pMac, pMsgBuf);
break;
case LIM_MLM_DISASSOC_CNF:
lim_process_mlm_disassoc_cnf(pMac, pMsgBuf);
break;
case LIM_MLM_DISASSOC_IND:
lim_process_mlm_disassoc_ind(pMac, pMsgBuf);
break;
case LIM_MLM_PURGE_STA_IND:
lim_process_mlm_purge_sta_ind(pMac, pMsgBuf);
break;
case LIM_MLM_DEAUTH_CNF:
lim_process_mlm_deauth_cnf(pMac, pMsgBuf);
break;
case LIM_MLM_DEAUTH_IND:
lim_process_mlm_deauth_ind(pMac, pMsgBuf);
break;
case LIM_MLM_SETKEYS_CNF:
lim_process_mlm_set_keys_cnf(pMac, pMsgBuf);
break;
case LIM_MLM_TSPEC_CNF:
break;
default:
break;
} /* switch (msgType) */
return;
} /*** end lim_process_mlm_rsp_messages() ***/
/**
* lim_process_mlm_start_cnf()
*
***FUNCTION:
* This function is called to processes MLM_START_CNF
* message from MLM State machine.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param pMsgBuf A pointer to the MLM message buffer
*
* @return None
*/
void lim_process_mlm_start_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
tpPESession psessionEntry = NULL;
tLimMlmStartCnf *pLimMlmStartCnf;
uint8_t smesessionId;
uint16_t smetransactionId;
uint8_t channelId;
uint8_t send_bcon_ind = false;
if (pMsgBuf == NULL) {
PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
return;
}
pLimMlmStartCnf = (tLimMlmStartCnf *) pMsgBuf;
psessionEntry = pe_find_session_by_session_id(pMac,
pLimMlmStartCnf->sessionId);
if (psessionEntry == NULL) {
PELOGE(lim_log(pMac, LOGE, FL(
"Session does Not exist with given sessionId "));)
return;
}
smesessionId = psessionEntry->smeSessionId;
smetransactionId = psessionEntry->transactionId;
if (psessionEntry->limSmeState != eLIM_SME_WT_START_BSS_STATE) {
/*
* Should not have received Start confirm from MLM
* in other states. Log error.
*/
PELOGE(lim_log(pMac, LOGE, FL
("received unexpected MLM_START_CNF in state %X"),
psessionEntry->limSmeState);)
return;
}
if (((tLimMlmStartCnf *) pMsgBuf)->resultCode == eSIR_SME_SUCCESS) {
/*
* Update global SME state so that Beacon Generation
* module starts writing Beacon frames into TFP's
* Beacon file register.
*/
psessionEntry->limSmeState = eLIM_SME_NORMAL_STATE;
MTRACE(mac_trace
(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
psessionEntry->limSmeState));
if (psessionEntry->bssType == eSIR_INFRA_AP_MODE)
lim_log(pMac, LOG1,
FL("*** Started BSS in INFRA AP SIDE***"));
else if (psessionEntry->bssType == eSIR_NDI_MODE)
lim_log(pMac, LOG1,
FL("*** Started BSS in NDI mode ***"));
else
lim_log(pMac, LOG1, FL("*** Started BSS ***"));
} else {
/* Start BSS is a failure */
pe_delete_session(pMac, psessionEntry);
psessionEntry = NULL;
PELOGE(lim_log(pMac, LOGE, FL("Start BSS Failed "));)
}
/* Send response to Host */
lim_send_sme_start_bss_rsp(pMac, eWNI_SME_START_BSS_RSP,
((tLimMlmStartCnf *)pMsgBuf)->resultCode,
psessionEntry, smesessionId, smetransactionId);
if ((psessionEntry != NULL) &&
(((tLimMlmStartCnf *) pMsgBuf)->resultCode ==
eSIR_SME_SUCCESS)) {
channelId = psessionEntry->pLimStartBssReq->channelId;
/* We should start beacon transmission only if the channel
* on which we are operating is non-DFS until the channel
* availability check is done. The PE will receive an explicit
* request from upper layers to start the beacon transmission
*/
if (!(LIM_IS_IBSS_ROLE(psessionEntry) ||
(LIM_IS_AP_ROLE(psessionEntry))))
return;
if (psessionEntry->ch_width == CH_WIDTH_160MHZ) {
send_bcon_ind = false;
} else if (psessionEntry->ch_width == CH_WIDTH_80P80MHZ) {
if ((cds_get_channel_state(channelId) !=
CHANNEL_STATE_DFS) &&
(cds_get_channel_state(psessionEntry->
ch_center_freq_seg1 -
SIR_80MHZ_START_CENTER_CH_DIFF) !=
CHANNEL_STATE_DFS))
send_bcon_ind = true;
} else {
if (cds_get_channel_state(channelId) !=
CHANNEL_STATE_DFS)
send_bcon_ind = true;
}
if (send_bcon_ind) {
/* Configure beacon and send beacons to HAL */
QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
FL("Start Beacon with ssid %s Ch %d"),
psessionEntry->ssId.ssId,
psessionEntry->currentOperChannel);
lim_send_beacon_ind(pMac, psessionEntry);
}
}
}
/*** end lim_process_mlm_start_cnf() ***/
/**
* lim_process_mlm_join_cnf() - Processes join confirmation
* @mac_ctx: Pointer to Global MAC structure
* @msg: A pointer to the MLM message buffer
*
* This Function handles the join confirmation message
* LIM_MLM_JOIN_CNF.
*
* Return: None
*/
void lim_process_mlm_join_cnf(tpAniSirGlobal mac_ctx,
uint32_t *msg)
{
tSirResultCodes result_code;
tLimMlmJoinCnf *join_cnf;
tpPESession session_entry;
join_cnf = (tLimMlmJoinCnf *) msg;
session_entry = pe_find_session_by_session_id(mac_ctx,
join_cnf->sessionId);
if (session_entry == NULL) {
lim_log(mac_ctx, LOGE, FL("SessionId:%d does not exist"),
join_cnf->sessionId);
return;
}
if (session_entry->limSmeState != eLIM_SME_WT_JOIN_STATE) {
lim_log(mac_ctx, LOGE,
FL("received unexpected MLM_JOIN_CNF in state %X"),
session_entry->limSmeState);
return;
}
result_code = ((tLimMlmJoinCnf *) msg)->resultCode;
/* Process Join confirm from MLM */
if (result_code == eSIR_SME_SUCCESS) {
lim_log(mac_ctx, LOG1, FL("***SessionId:%d Joined ESS ***"),
join_cnf->sessionId);
/* Setup hardware upfront */
if (lim_sta_send_add_bss_pre_assoc(mac_ctx, false,
session_entry) == eSIR_SUCCESS)
return;
else
result_code = eSIR_SME_REFUSED;
}
/* Join failure */
session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
/* Send Join response to Host */
lim_handle_sme_join_result(mac_ctx, result_code,
((tLimMlmJoinCnf *) msg)->protStatusCode, session_entry);
return;
}
/**
* lim_send_mlm_assoc_req() - Association request will be processed
* mac_ctx: Pointer to Global MAC structure
* session_entry: Pointer to session etnry
*
* This function is sends ASSOC request MLM message to MLM State machine.
* ASSOC request packet would be by picking parameters from psessionEntry
* automatically based on the current state of MLM state machine.
* ASSUMPTIONS:
* this function is called in middle of connection state machine and is
* expected to be called after auth cnf has been received or after ASSOC rsp
* with TRY_AGAIN_LATER was received and required time has elapsed after that.
*
* Return: None
*/
static void lim_send_mlm_assoc_req(tpAniSirGlobal mac_ctx,
tpPESession session_entry)
{
tLimMlmAssocReq *assoc_req;
uint32_t val;
uint16_t caps;
uint32_t tele_bcn = 0;
tpSirMacCapabilityInfo cap_info;
/* Successful MAC based authentication. Trigger Association with BSS */
lim_log(mac_ctx, LOG1, FL("SessionId:%d Authenticated with BSS"),
session_entry->peSessionId);
if (NULL == session_entry->pLimJoinReq) {
lim_log(mac_ctx, LOGE, FL("Join Request is NULL."));
/* No need to Assert. JOIN timeout will handle this error */
return;
}
assoc_req = qdf_mem_malloc(sizeof(tLimMlmAssocReq));
if (NULL == assoc_req) {
lim_log(mac_ctx, LOGP,
FL("call to AllocateMemory failed for mlmAssocReq"));
return;
}
val = sizeof(tSirMacAddr);
sir_copy_mac_addr(assoc_req->peerMacAddr, session_entry->bssId);
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
(uint32_t *) &assoc_req->assocFailureTimeout)
!= eSIR_SUCCESS) {
/* Could not get AssocFailureTimeout value from CFG.*/
lim_log(mac_ctx, LOGP,
FL("could not retrieve AssocFailureTimeout value"));
}
if (cfg_get_capability_info(mac_ctx, &caps, session_entry)
!= eSIR_SUCCESS)
/* Could not get Capabilities value from CFG.*/
lim_log(mac_ctx, LOGP,
FL("could not retrieve Capabilities value"));
/* Clear spectrum management bit if AP doesn't support it */
if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
LIM_SPECTRUM_MANAGEMENT_BIT_MASK))
/*
* AP doesn't support spectrum management
* clear spectrum management bit
*/
caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK);
/*
* RM capability should be independent of AP's capabilities
* Refer 8.4.1.4 Capability Information field in 802.11-2012
* Do not modify it.
*/
/* Clear short preamble bit if AP does not support it */
if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
(LIM_SHORT_PREAMBLE_BIT_MASK))) {
caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK);
lim_log(mac_ctx, LOG1,
FL("Clearing short preamble:no AP support"));
}
/* Clear immediate block ack bit if AP does not support it */
if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
(LIM_IMMEDIATE_BLOCK_ACK_MASK))) {
caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK);
lim_log(mac_ctx, LOG1,
FL("Clearing Immed Blk Ack:no AP support"));
}
assoc_req->capabilityInfo = caps;
cap_info = ((tpSirMacCapabilityInfo) &assoc_req->capabilityInfo);
lim_log(mac_ctx, LOG3, FL("Capabilities to be used in AssocReq=0x%X,"
"privacy bit=%x shortSlotTime %x"), caps,
cap_info->privacy,
cap_info->shortSlotTime);
/*
* If telescopic beaconing is enabled, set listen interval to
* WNI_CFG_TELE_BCN_MAX_LI
*/
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TELE_BCN_WAKEUP_EN, &tele_bcn)
!= eSIR_SUCCESS)
lim_log(mac_ctx, LOGP,
FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN"));
val = WNI_CFG_LISTEN_INTERVAL_STADEF;
if (tele_bcn) {
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
eSIR_SUCCESS)
/*
* Could not get ListenInterval value
* from CFG. Log error.
*/
lim_log(mac_ctx, LOGP,
FL("could not retrieve ListenInterval"));
} else {
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_LISTEN_INTERVAL,
&val) != eSIR_SUCCESS)
/*
* Could not get ListenInterval value
* from CFG. Log error.
*/
lim_log(mac_ctx, LOGP,
FL("could not retrieve ListenInterval"));
}
#ifdef FEATURE_WLAN_DIAG_SUPPORT
lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_REQ_EVENT,
session_entry, eSIR_SUCCESS, eSIR_SUCCESS);
#endif
assoc_req->listenInterval = (uint16_t) val;
/* Update PE session ID */
assoc_req->sessionId = session_entry->peSessionId;
session_entry->limPrevSmeState = session_entry->limSmeState;
session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId, session_entry->limSmeState));
lim_post_mlm_message(mac_ctx, LIM_MLM_ASSOC_REQ,
(uint32_t *) assoc_req);
}
#ifdef WLAN_FEATURE_11W
/**
* lim_pmf_comeback_timer_callback() -PMF callback handler
* @context: Timer context
*
* This function is called to processes the PMF comeback
* callback
*
* Return: None
*/
void lim_pmf_comeback_timer_callback(void *context)
{
tComebackTimerInfo *info = (tComebackTimerInfo *) context;
tpAniSirGlobal mac_ctx = info->pMac;
tpPESession psessionEntry = &mac_ctx->lim.gpSession[info->sessionID];
lim_log(mac_ctx, LOGE,
FL("comeback later timer expired. sending MLM ASSOC req"));
/* set MLM state such that ASSOC REQ packet will be sent out */
psessionEntry->limPrevMlmState = info->limPrevMlmState;
psessionEntry->limMlmState = info->limMlmState;
lim_send_mlm_assoc_req(mac_ctx, psessionEntry);
}
#endif /* WLAN_FEATURE_11W */
/**
* lim_process_mlm_auth_cnf()-Process Auth confirmation
* @mac_ctx: Pointer to Global MAC structure
* @msg: A pointer to the MLM message buffer
*
* This function is called to processes MLM_AUTH_CNF
* message from MLM State machine.
*
* Return: None
*/
void lim_process_mlm_auth_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg)
{
tAniAuthType auth_type, auth_mode;
tLimMlmAuthReq *auth_req;
tLimMlmAuthCnf *auth_cnf;
tpPESession session_entry;
if (msg == NULL) {
lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
return;
}
auth_cnf = (tLimMlmAuthCnf *) msg;
session_entry = pe_find_session_by_session_id(mac_ctx,
auth_cnf->sessionId);
if (session_entry == NULL) {
lim_log(mac_ctx, LOGE, FL("SessionId:%d session doesn't exist"),
auth_cnf->sessionId);
return;
}
if ((session_entry->limSmeState != eLIM_SME_WT_AUTH_STATE &&
session_entry->limSmeState != eLIM_SME_WT_PRE_AUTH_STATE) ||
LIM_IS_AP_ROLE(session_entry)) {
/**
* Should not have received AUTH confirm
* from MLM in other states or on AP.
* Log error
*/
lim_log(mac_ctx, LOGE,
FL("SessionId:%d received MLM_AUTH_CNF in state %X"),
session_entry->peSessionId, session_entry->limSmeState);
return;
}
if (auth_cnf->resultCode == eSIR_SME_SUCCESS) {
if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE) {
lim_send_mlm_assoc_req(mac_ctx, session_entry);
} else {
/*
* Successful Pre-authentication. Send
* Pre-auth response to host
*/
session_entry->limSmeState =
session_entry->limPrevSmeState;
MTRACE(mac_trace
(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
}
/* Return for success case */
return;
}
/*
* Failure case handle:
* Process AUTH confirm from MLM
*/
if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE) {
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_AUTHENTICATION_TYPE,
(uint32_t *) &auth_type) != eSIR_SUCCESS) {
/*
* Could not get AuthType value from CFG.
* Log error.
*/
lim_log(mac_ctx, LOGP,
FL("Fail to retrieve AuthType value"));
}
} else {
auth_type = mac_ctx->lim.gLimPreAuthType;
}
if ((auth_type == eSIR_AUTO_SWITCH) &&
(auth_cnf->authType == eSIR_SHARED_KEY) &&
((eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS ==
auth_cnf->protStatusCode) ||
(auth_cnf->resultCode == eSIR_SME_AUTH_TIMEOUT_RESULT_CODE))) {
/*
* When shared authentication fails with reason
* code "13" and authType set to 'auto switch',
* Try with open Authentication
*/
auth_mode = eSIR_OPEN_SYSTEM;
/* Trigger MAC based Authentication */
auth_req = qdf_mem_malloc(sizeof(tLimMlmAuthReq));
if (NULL == auth_req) {
/* Log error */
lim_log(mac_ctx, LOGP,
FL("mlmAuthReq :Memory alloc failed "));
return;
}
if (session_entry->limSmeState ==
eLIM_SME_WT_AUTH_STATE) {
sir_copy_mac_addr(auth_req->peerMacAddr,
session_entry->bssId);
} else {
qdf_mem_copy((uint8_t *)&auth_req->peerMacAddr,
(uint8_t *)&mac_ctx->lim.gLimPreAuthPeerAddr,
sizeof(tSirMacAddr));
}
auth_req->authType = auth_mode;
/* Update PE session Id */
auth_req->sessionId = auth_cnf->sessionId;
if (wlan_cfg_get_int(mac_ctx,
WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
(uint32_t *) &auth_req->authFailureTimeout)
!= eSIR_SUCCESS) {
/*
* Could not get AuthFailureTimeout value from CFG.
* Log error.
*/
lim_log(mac_ctx, LOGP,
FL("Fail:retrieve AuthFailureTimeout "));
}
lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ,
(uint32_t *) auth_req);
return;
} else {
/* MAC based authentication failure */
if (session_entry->limSmeState ==
eLIM_SME_WT_AUTH_STATE) {
lim_log(mac_ctx, LOGE,
FL("Auth Failure occurred."));
session_entry->limSmeState =
eLIM_SME_JOIN_FAILURE_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
session_entry->limMlmState =
eLIM_MLM_IDLE_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
session_entry->peSessionId,
session_entry->limMlmState));
/*
* Need to send Join response with
* auth failure to Host.
*/
lim_handle_sme_join_result(mac_ctx,
auth_cnf->resultCode,
auth_cnf->protStatusCode,
session_entry);
} else {
/*
* Pre-authentication failure.
* Send Pre-auth failure response to host
*/
session_entry->limSmeState =
session_entry->limPrevSmeState;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
}
}
}
/**
* lim_process_mlm_assoc_cnf() - Process association confirmation
* @mac_ctx: Pointer to Global MAC structure
* @msg: A pointer to the MLM message buffer
*
* This function is called to processes MLM_ASSOC_CNF
* message from MLM State machine.
*
* Return: None
*/
void lim_process_mlm_assoc_cnf(tpAniSirGlobal mac_ctx,
uint32_t *msg)
{
tpPESession session_entry;
tLimMlmAssocCnf *assoc_cnf;
if (msg == NULL) {
lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
return;
}
assoc_cnf = (tLimMlmAssocCnf *) msg;
session_entry = pe_find_session_by_session_id(mac_ctx,
assoc_cnf->sessionId);
if (session_entry == NULL) {
lim_log(mac_ctx, LOGE,
FL("SessionId:%d Session does not exist"),
assoc_cnf->sessionId);
return;
}
if (session_entry->limSmeState != eLIM_SME_WT_ASSOC_STATE ||
LIM_IS_AP_ROLE(session_entry)) {
/*
* Should not have received Assocication confirm
* from MLM in other states OR on AP.
* Log error
*/
lim_log(mac_ctx, LOGE,
FL("SessionId:%d Received MLM_ASSOC_CNF in state %X"),
session_entry->peSessionId, session_entry->limSmeState);
return;
}
if (((tLimMlmAssocCnf *) msg)->resultCode != eSIR_SME_SUCCESS) {
/* Association failure */
lim_log(mac_ctx, LOG1, FL("SessionId:%d Association failure resultCode: %d limSmeState:%d"),
session_entry->peSessionId,
((tLimMlmAssocCnf *) msg)->resultCode,
session_entry->limSmeState);
/* If driver gets deauth when its waiting for ADD_STA_RSP then
* we need to do DEL_STA followed by DEL_BSS. So based on below
* reason-code here we decide whether to do only DEL_BSS or
* DEL_STA + DEL_BSS.
*/
if (((tLimMlmAssocCnf *) msg)->resultCode !=
eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA)
session_entry->limSmeState =
eLIM_SME_JOIN_FAILURE_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId, mac_ctx->lim.gLimSmeState));
/*
* Need to send Join response with
* Association failure to Host.
*/
lim_handle_sme_join_result(mac_ctx,
((tLimMlmAssocCnf *) msg)->resultCode,
((tLimMlmAssocCnf *) msg)->protStatusCode,
session_entry);
} else {
/* Successful Association */
lim_log(mac_ctx, LOG1, FL("SessionId:%d Associated with BSS"),
session_entry->peSessionId);
session_entry->limSmeState = eLIM_SME_LINK_EST_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
/**
* Need to send Join response with
* Association success to Host.
*/
lim_handle_sme_join_result(mac_ctx,
((tLimMlmAssocCnf *) msg)->resultCode,
((tLimMlmAssocCnf *) msg)->protStatusCode,
session_entry);
}
}
/**
* lim_fill_assoc_ind_params() - Initialize association indication
* mac_ctx: Pointer to Global MAC structure
* assoc_ind: PE association indication structure
* sme_assoc_ind: SME association indication
* session_entry: PE session entry
*
* This function is called to initialzie the association
* indication strucutre to process association indication.
*
* Return: None
*/
static void
lim_fill_assoc_ind_params(tpAniSirGlobal mac_ctx,
tpLimMlmAssocInd assoc_ind, tSirSmeAssocInd *sme_assoc_ind,
tpPESession session_entry)
{
sme_assoc_ind->length = sizeof(tSirSmeAssocInd);
sme_assoc_ind->sessionId = session_entry->smeSessionId;
/* Required for indicating the frames to upper layer */
sme_assoc_ind->assocReqLength = assoc_ind->assocReqLength;
sme_assoc_ind->assocReqPtr = assoc_ind->assocReqPtr;
sme_assoc_ind->beaconPtr = session_entry->beacon;
sme_assoc_ind->beaconLength = session_entry->bcnLen;
/* Fill in peerMacAddr */
qdf_mem_copy(sme_assoc_ind->peerMacAddr, assoc_ind->peerMacAddr,
sizeof(tSirMacAddr));
/* Fill in aid */
sme_assoc_ind->aid = assoc_ind->aid;
/* Fill in bssId */
qdf_mem_copy(sme_assoc_ind->bssId, session_entry->bssId,
sizeof(tSirMacAddr));
/* Fill in authType */
sme_assoc_ind->authType = assoc_ind->authType;
/* Fill in ssId */
qdf_mem_copy((uint8_t *) &sme_assoc_ind->ssId,
(uint8_t *) &(assoc_ind->ssId), assoc_ind->ssId.length + 1);
sme_assoc_ind->rsnIE.length = assoc_ind->rsnIE.length;
qdf_mem_copy((uint8_t *) &sme_assoc_ind->rsnIE.rsnIEdata,
(uint8_t *) &(assoc_ind->rsnIE.rsnIEdata),
assoc_ind->rsnIE.length);
#ifdef FEATURE_WLAN_WAPI
sme_assoc_ind->wapiIE.length = assoc_ind->wapiIE.length;
qdf_mem_copy((uint8_t *) &sme_assoc_ind->wapiIE.wapiIEdata,
(uint8_t *) &(assoc_ind->wapiIE.wapiIEdata),
assoc_ind->wapiIE.length);
#endif
sme_assoc_ind->addIE.length = assoc_ind->addIE.length;
qdf_mem_copy((uint8_t *) &sme_assoc_ind->addIE.addIEdata,
(uint8_t *) &(assoc_ind->addIE.addIEdata),
assoc_ind->addIE.length);
/* Copy the new TITAN capabilities */
sme_assoc_ind->spectrumMgtIndicator = assoc_ind->spectrumMgtIndicator;
if (assoc_ind->spectrumMgtIndicator == eSIR_TRUE) {
sme_assoc_ind->powerCap.minTxPower =
assoc_ind->powerCap.minTxPower;
sme_assoc_ind->powerCap.maxTxPower =
assoc_ind->powerCap.maxTxPower;
sme_assoc_ind->supportedChannels.numChnl =
assoc_ind->supportedChannels.numChnl;
qdf_mem_copy((uint8_t *) &sme_assoc_ind->supportedChannels.
channelList,
(uint8_t *) &(assoc_ind->supportedChannels.channelList),
assoc_ind->supportedChannels.numChnl);
}
qdf_mem_copy(&sme_assoc_ind->chan_info, &assoc_ind->chan_info,
sizeof(tSirSmeChanInfo));
/* Fill in WmmInfo */
sme_assoc_ind->wmmEnabledSta = assoc_ind->WmmStaInfoPresent;
}
/**
* lim_process_mlm_assoc_ind()
*
***FUNCTION:
* This function is called to processes MLM_ASSOC_IND
* message from MLM State machine.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param pMsgBuf A pointer to the MLM message buffer
*
* @return None
*/
void lim_process_mlm_assoc_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
uint32_t len;
tSirMsgQ msgQ;
tSirSmeAssocInd *pSirSmeAssocInd;
tpDphHashNode pStaDs = 0;
tpPESession psessionEntry;
if (pMsgBuf == NULL) {
PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
return;
}
psessionEntry = pe_find_session_by_session_id(pMac,
((tpLimMlmAssocInd) pMsgBuf)->
sessionId);
if (psessionEntry == NULL) {
lim_log(pMac, LOGE,
FL("Session Does not exist for given sessionId"));
return;
}
/* / Inform Host of STA association */
len = sizeof(tSirSmeAssocInd);
pSirSmeAssocInd = qdf_mem_malloc(len);
if (NULL == pSirSmeAssocInd) {
/* Log error */
lim_log(pMac, LOGP,
FL
("call to AllocateMemory failed for eWNI_SME_ASSOC_IND"));
return;
}
pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND;
lim_fill_assoc_ind_params(pMac, (tpLimMlmAssocInd) pMsgBuf, pSirSmeAssocInd,
psessionEntry);
msgQ.type = eWNI_SME_ASSOC_IND;
msgQ.bodyptr = pSirSmeAssocInd;
msgQ.bodyval = 0;
pStaDs = dph_get_hash_entry(pMac,
((tpLimMlmAssocInd) pMsgBuf)->aid,
&psessionEntry->dph.dphHashTable);
if (!pStaDs) { /* good time to panic... */
lim_log(pMac, LOGE,
FL
("MLM AssocInd: Station context no longer valid (aid %d)"),
((tpLimMlmAssocInd) pMsgBuf)->aid);
qdf_mem_free(pSirSmeAssocInd);
return;
}
pSirSmeAssocInd->staId = pStaDs->staIndex;
pSirSmeAssocInd->reassocReq = pStaDs->mlmStaContext.subType;
pSirSmeAssocInd->timingMeasCap = pStaDs->timingMeasCap;
MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
psessionEntry->peSessionId, msgQ.type));
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
lim_diag_event_report(pMac, WLAN_PE_DIAG_ASSOC_IND_EVENT, psessionEntry, 0,
0);
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
lim_sys_process_mmh_msg_api(pMac, &msgQ, ePROT);
PELOG1(lim_log(pMac, LOG1,
FL
("Create CNF_WAIT_TIMER after received LIM_MLM_ASSOC_IND"));
)
/*
** turn on a timer to detect the loss of ASSOC CNF
**/
lim_activate_cnf_timer(pMac,
(uint16_t) ((tpLimMlmAssocInd) pMsgBuf)->aid,
psessionEntry);
} /*** end lim_process_mlm_assoc_ind() ***/
/**
* lim_process_mlm_disassoc_ind()
*
***FUNCTION:
* This function is called to processes MLM_DISASSOC_IND
* message from MLM State machine.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param pMsgBuf A pointer to the MLM message buffer
*
* @return None
*/
void lim_process_mlm_disassoc_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
tLimMlmDisassocInd *pMlmDisassocInd;
tpPESession psessionEntry;
pMlmDisassocInd = (tLimMlmDisassocInd *) pMsgBuf;
psessionEntry = pe_find_session_by_session_id(pMac,
pMlmDisassocInd->sessionId);
if (psessionEntry == NULL) {
lim_log(pMac, LOGP,
FL("Session Does not exist for given sessionID"));
return;
}
switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
case eLIM_STA_IN_IBSS_ROLE:
break;
case eLIM_STA_ROLE:
psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
MTRACE(mac_trace
(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
psessionEntry->limSmeState));
break;
default: /* eLIM_AP_ROLE */
PELOG1(lim_log(pMac, LOG1,
FL("*** Peer staId=%d Disassociated ***"),
pMlmDisassocInd->aid);
)
/* Send SME_DISASOC_IND after Polaris cleanup */
/* (after receiving LIM_MLM_PURGE_STA_IND) */
break;
} /* end switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) */
} /*** end lim_process_mlm_disassoc_ind() ***/
/**
* lim_process_mlm_disassoc_cnf() - Processes disassociation
* @mac_ctx: Pointer to Global MAC structure
* @msg: A pointer to the MLM message buffer
*
* This function is called to processes MLM_DISASSOC_CNF
* message from MLM State machine.
*
* Return: None
*/
void lim_process_mlm_disassoc_cnf(tpAniSirGlobal mac_ctx,
uint32_t *msg)
{
tSirResultCodes result_code;
tLimMlmDisassocCnf *disassoc_cnf;
tpPESession session_entry;
disassoc_cnf = (tLimMlmDisassocCnf *) msg;
session_entry =
pe_find_session_by_session_id(mac_ctx, disassoc_cnf->sessionId);
if (session_entry == NULL) {
lim_log(mac_ctx, LOGE,
FL("session Does not exist for given session Id"));
return;
}
result_code = (tSirResultCodes)(disassoc_cnf->disassocTrigger ==
eLIM_LINK_MONITORING_DISASSOC) ?
eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
disassoc_cnf->resultCode;
if (LIM_IS_STA_ROLE(session_entry)) {
/* Disassociate Confirm from MLM */
if ((session_entry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
&& (session_entry->limSmeState !=
eLIM_SME_WT_DEAUTH_STATE)) {
/*
* Should not have received
* Disassocate confirm
* from MLM in other states.Log error
*/
lim_log(mac_ctx, LOGE,
FL("received MLM_DISASSOC_CNF in state %X"),
session_entry->limSmeState);
return;
}
if (mac_ctx->lim.gLimRspReqd)
mac_ctx->lim.gLimRspReqd = false;
if (disassoc_cnf->disassocTrigger ==
eLIM_PROMISCUOUS_MODE_DISASSOC) {
if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS)
session_entry->limSmeState =
session_entry->limPrevSmeState;
else
session_entry->limSmeState =
eLIM_SME_OFFLINE_STATE;
MTRACE(mac_trace
(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
} else {
if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS)
session_entry->limSmeState =
session_entry->limPrevSmeState;
else
session_entry->limSmeState =
eLIM_SME_IDLE_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
lim_send_sme_disassoc_ntf(mac_ctx,
disassoc_cnf->peerMacAddr, result_code,
disassoc_cnf->disassocTrigger,
disassoc_cnf->aid, session_entry->smeSessionId,
session_entry->transactionId, session_entry);
}
} else if (LIM_IS_AP_ROLE(session_entry)) {
lim_send_sme_disassoc_ntf(mac_ctx, disassoc_cnf->peerMacAddr,
result_code, disassoc_cnf->disassocTrigger,
disassoc_cnf->aid, session_entry->smeSessionId,
session_entry->transactionId, session_entry);
}
}
/**
* lim_process_mlm_deauth_ind()
*
***FUNCTION:
* This function is called to processes MLM_DEAUTH_IND
* message from MLM State machine.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param pMsgBuf A pointer to the MLM message buffer
*
* @return None
*/
void lim_process_mlm_deauth_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
tLimMlmDeauthInd *pMlmDeauthInd;
tpPESession psessionEntry;
uint8_t sessionId;
pMlmDeauthInd = (tLimMlmDeauthInd *) pMsgBuf;
psessionEntry = pe_find_session_by_bssid(pMac,
pMlmDeauthInd->peerMacAddr, &sessionId);
if (psessionEntry == NULL) {
lim_log(pMac, LOGE,
FL("session does not exist for Addr:" MAC_ADDRESS_STR),
MAC_ADDR_ARRAY(pMlmDeauthInd->peerMacAddr));
return;
}
switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
case eLIM_STA_IN_IBSS_ROLE:
break;
case eLIM_STA_ROLE:
psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
MTRACE(mac_trace
(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
psessionEntry->limSmeState));
default: /* eLIM_AP_ROLE */
{
PELOG1(lim_log(pMac, LOG1,
FL
("*** Received Deauthentication from staId=%d ***"),
pMlmDeauthInd->aid);
)
}
/* Send SME_DEAUTH_IND after Polaris cleanup */
/* (after receiving LIM_MLM_PURGE_STA_IND) */
break;
} /* end switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) */
} /*** end lim_process_mlm_deauth_ind() ***/
/**
* lim_process_mlm_deauth_cnf()
*
***FUNCTION:
* This function is called to processes MLM_DEAUTH_CNF
* message from MLM State machine.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param pMsgBuf A pointer to the MLM message buffer
*
* @return None
*/
void lim_process_mlm_deauth_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
uint16_t aid;
tSirResultCodes resultCode;
tLimMlmDeauthCnf *pMlmDeauthCnf;
tpPESession psessionEntry;
if (pMsgBuf == NULL) {
PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
return;
}
pMlmDeauthCnf = (tLimMlmDeauthCnf *) pMsgBuf;
psessionEntry = pe_find_session_by_session_id(pMac,
pMlmDeauthCnf->sessionId);
if (psessionEntry == NULL) {
PELOGE(lim_log
(pMac, LOGE,
FL("session does not exist for given session Id "));
)
return;
}
resultCode = (tSirResultCodes)
(pMlmDeauthCnf->deauthTrigger ==
eLIM_LINK_MONITORING_DEAUTH) ?
eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
pMlmDeauthCnf->resultCode;
aid = LIM_IS_AP_ROLE(psessionEntry) ? pMlmDeauthCnf->aid : 1;
if (LIM_IS_STA_ROLE(psessionEntry)) {
/* Deauth Confirm from MLM */
if ((psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
&& psessionEntry->limSmeState !=
eLIM_SME_WT_DEAUTH_STATE) {
/**
* Should not have received Deauth confirm
* from MLM in other states.
* Log error
*/
PELOGE(lim_log(pMac, LOGE,
FL
("received unexpected MLM_DEAUTH_CNF in state %X"),
psessionEntry->limSmeState);)
return;
}
if (pMlmDeauthCnf->resultCode == eSIR_SME_SUCCESS) {
psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
PELOG1(lim_log(pMac, LOG1,
FL("*** Deauthenticated with BSS ***"));)
} else
psessionEntry->limSmeState =
psessionEntry->limPrevSmeState;
MTRACE(mac_trace
(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
psessionEntry->limSmeState));
if (pMac->lim.gLimRspReqd)
pMac->lim.gLimRspReqd = false;
}
/* On STA or on BASIC AP, send SME_DEAUTH_RSP to host */
lim_send_sme_deauth_ntf(pMac, pMlmDeauthCnf->peer_macaddr.bytes,
resultCode,
pMlmDeauthCnf->deauthTrigger,
aid, psessionEntry->smeSessionId,
psessionEntry->transactionId);
} /*** end lim_process_mlm_deauth_cnf() ***/
/**
* lim_process_mlm_purge_sta_ind()
*
***FUNCTION:
* This function is called to processes MLM_PURGE_STA_IND
* message from MLM State machine.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param pMsgBuf A pointer to the MLM message buffer
*
* @return None
*/
void lim_process_mlm_purge_sta_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
tSirResultCodes resultCode;
tpLimMlmPurgeStaInd pMlmPurgeStaInd;
tpPESession psessionEntry;
if (pMsgBuf == NULL) {
PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
return;
}
pMlmPurgeStaInd = (tpLimMlmPurgeStaInd) pMsgBuf;
psessionEntry = pe_find_session_by_session_id(pMac,
pMlmPurgeStaInd->sessionId);
if (psessionEntry == NULL) {
PELOGE(lim_log
(pMac, LOGE,
FL("session does not exist for given bssId"));
)
return;
}
/* Purge STA indication from MLM */
resultCode = (tSirResultCodes) pMlmPurgeStaInd->reasonCode;
switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
case eLIM_STA_IN_IBSS_ROLE:
break;
case eLIM_STA_ROLE:
default: /* eLIM_AP_ROLE */
if (LIM_IS_STA_ROLE(psessionEntry) &&
(psessionEntry->limSmeState !=
eLIM_SME_WT_DISASSOC_STATE) &&
(psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) {
/**
* Should not have received
* Purge STA indication
* from MLM in other states.
* Log error
*/
PELOGE(lim_log(pMac, LOGE,
FL
("received unexpected MLM_PURGE_STA_IND in state %X"),
psessionEntry->limSmeState);
)
break;
}
PELOG1(lim_log(pMac, LOG1,
FL("*** Cleanup completed for staId=%d ***"),
pMlmPurgeStaInd->aid);
)
if (LIM_IS_STA_ROLE(psessionEntry)) {
psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
MTRACE(mac_trace
(pMac, TRACE_CODE_SME_STATE,
psessionEntry->peSessionId,
psessionEntry->limSmeState));
}
if (pMlmPurgeStaInd->purgeTrigger == eLIM_PEER_ENTITY_DEAUTH) {
lim_send_sme_deauth_ntf(pMac,
pMlmPurgeStaInd->peerMacAddr,
resultCode,
pMlmPurgeStaInd->purgeTrigger,
pMlmPurgeStaInd->aid,
psessionEntry->smeSessionId,
psessionEntry->transactionId);
} else
lim_send_sme_disassoc_ntf(pMac,
pMlmPurgeStaInd->peerMacAddr,
resultCode,
pMlmPurgeStaInd->purgeTrigger,
pMlmPurgeStaInd->aid,
psessionEntry->smeSessionId,
psessionEntry->transactionId,
psessionEntry);
} /* end switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) */
} /*** end lim_process_mlm_purge_sta_ind() ***/
/**
* lim_process_mlm_set_keys_cnf()
*
***FUNCTION:
* This function is called to processes MLM_SETKEYS_CNF
* message from MLM State machine.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param pMsgBuf A pointer to the MLM message buffer
*
* @return None
*/
void lim_process_mlm_set_keys_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
/* Prepare and send SME_SETCONTEXT_RSP message */
tLimMlmSetKeysCnf *pMlmSetKeysCnf;
tpPESession psessionEntry;
uint16_t aid;
tpDphHashNode sta_ds;
if (pMsgBuf == NULL) {
PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
return;
}
pMlmSetKeysCnf = (tLimMlmSetKeysCnf *) pMsgBuf;
psessionEntry = pe_find_session_by_session_id(pMac,
pMlmSetKeysCnf->sessionId);
if (psessionEntry == NULL) {
PELOGE(lim_log
(pMac, LOGE,
FL("session does not exist for given sessionId "));
)
return;
}
psessionEntry->is_key_installed = 0;
lim_log(pMac, LOG1,
FL("Received MLM_SETKEYS_CNF with resultCode = %d"),
pMlmSetKeysCnf->resultCode);
/* if the status is success keys are installed in the
* Firmware so we can set the protection bit
*/
if (eSIR_SME_SUCCESS == pMlmSetKeysCnf->resultCode) {
if (pMlmSetKeysCnf->key_len_nonzero)
psessionEntry->is_key_installed = 1;
if (LIM_IS_AP_ROLE(psessionEntry)) {
sta_ds = dph_lookup_hash_entry(pMac,
pMlmSetKeysCnf->peer_macaddr.bytes,
&aid, &psessionEntry->dph.dphHashTable);
if (sta_ds != NULL && pMlmSetKeysCnf->key_len_nonzero)
sta_ds->is_key_installed = 1;
}
}
lim_log(pMac, LOG1,
FL("is_key_installed = %d"),
psessionEntry->is_key_installed);
lim_send_sme_set_context_rsp(pMac,
pMlmSetKeysCnf->peer_macaddr,
1,
(tSirResultCodes) pMlmSetKeysCnf->resultCode,
psessionEntry, psessionEntry->smeSessionId,
psessionEntry->transactionId);
} /*** end lim_process_mlm_set_keys_cnf() ***/
/**
* lim_handle_sme_join_result() - Handles sme join result
* @mac_ctx: Pointer to Global MAC structure
* @result_code: Failure code to be sent
* @prot_status_code : Protocol status code
* @session_entry: PE session handle
*
* This function is called to process join/auth/assoc failures
* upon receiving MLM_JOIN/AUTH/ASSOC_CNF with a failure code or
* MLM_ASSOC_CNF with a success code in case of STA role and
* MLM_JOIN_CNF with success in case of STA in IBSS role.
*
* Return: None
*/
void lim_handle_sme_join_result(tpAniSirGlobal mac_ctx,
tSirResultCodes result_code, uint16_t prot_status_code,
tpPESession session_entry)
{
tpDphHashNode sta_ds = NULL;
uint8_t sme_session_id;
uint16_t sme_trans_id;
if (session_entry == NULL) {
lim_log(mac_ctx, LOGE, FL("psessionEntry is NULL "));
return;
}
sme_session_id = session_entry->smeSessionId;
sme_trans_id = session_entry->transactionId;
/*
* When associations is failed , delete the session created
* and pass NULL to limsendsmeJoinReassocRsp()
*/
if (result_code != eSIR_SME_SUCCESS) {
sta_ds =
dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
&session_entry->dph.dphHashTable);
if (sta_ds != NULL) {
sta_ds->mlmStaContext.disassocReason =
eSIR_MAC_UNSPEC_FAILURE_REASON;
sta_ds->mlmStaContext.cleanupTrigger =
eLIM_JOIN_FAILURE;
sta_ds->mlmStaContext.resultCode = result_code;
sta_ds->mlmStaContext.protStatusCode = prot_status_code;
/*
* FIX_ME: at the end of lim_cleanup_rx_path,
* make sure PE is sending eWNI_SME_JOIN_RSP
* to SME
*/
lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);
qdf_mem_free(session_entry->pLimJoinReq);
session_entry->pLimJoinReq = NULL;
/* Cleanup if add bss failed */
if (session_entry->add_bss_failed) {
dph_delete_hash_entry(mac_ctx,
sta_ds->staAddr, sta_ds->assocId,
&session_entry->dph.dphHashTable);
goto error;
}
return;
}
qdf_mem_free(session_entry->pLimJoinReq);
session_entry->pLimJoinReq = NULL;
}
error:
/* Delete the session if JOIN failure occurred. */
if (result_code != eSIR_SME_SUCCESS) {
if (lim_set_link_state
(mac_ctx, eSIR_LINK_DOWN_STATE,
session_entry->bssId,
session_entry->selfMacAddr, NULL,
NULL) != eSIR_SUCCESS)
lim_log(mac_ctx, LOGE,
FL("Failed to set the LinkState."));
pe_delete_session(mac_ctx, session_entry);
session_entry = NULL;
}
lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, result_code,
prot_status_code, session_entry, sme_session_id, sme_trans_id);
}
/**
* lim_process_mlm_add_sta_rsp()
*
***FUNCTION:
* This function is called to process a WMA_ADD_STA_RSP from HAL.
* Upon receipt of this message from HAL, MLME -
* > Determines the "state" in which this message was received
* > Forwards it to the appropriate callback
*
***ASSUMPTIONS:
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param tSirMsgQ The MsgQ header, which contains the response buffer
*
* @return None
*/
void lim_process_mlm_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
tpPESession psessionEntry)
{
/* we need to process the deferred message since the initiating req. there might be nested request. */
/* in the case of nested request the new request initiated from the response will take care of resetting */
/* the deffered flag. */
SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
if (LIM_IS_AP_ROLE(psessionEntry)) {
lim_process_ap_mlm_add_sta_rsp(pMac, limMsgQ, psessionEntry);
return;
}
lim_process_sta_mlm_add_sta_rsp(pMac, limMsgQ, psessionEntry);
}
/**
* lim_process_sta_mlm_add_sta_rsp () - Process add sta response
* @mac_ctx: Pointer to mac context
* @msg: tpSirMsgQan Message structure
* @session_entry: PE session entry
*
* Process ADD STA response sent from WMA and posts results
* to SME.
*
* Return: Null
*/
void lim_process_sta_mlm_add_sta_rsp(tpAniSirGlobal mac_ctx,
tpSirMsgQ msg, tpPESession session_entry)
{
tLimMlmAssocCnf mlm_assoc_cnf;
tpDphHashNode sta_ds;
uint32_t msg_type = LIM_MLM_ASSOC_CNF;
tpAddStaParams add_sta_params = (tpAddStaParams) msg->bodyptr;
tpPESession ft_session = NULL;
uint8_t ft_session_id;
if (NULL == add_sta_params) {
lim_log(mac_ctx, LOGE, FL("Encountered NULL Pointer"));
return;
}
if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
msg_type = LIM_MLM_REASSOC_CNF;
if (true == session_entry->fDeauthReceived) {
lim_log(mac_ctx, LOGE,
FL("Received Deauth frame in ADD_STA_RESP state"));
if (QDF_STATUS_SUCCESS == add_sta_params->status) {
lim_log(mac_ctx, LOGE,
FL("ADD_STA success, send update result code with eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA staIdx: %d limMlmState: %d"),
add_sta_params->staIdx,
session_entry->limMlmState);
if (session_entry->limSmeState ==
eLIM_SME_WT_REASSOC_STATE)
msg_type = LIM_MLM_REASSOC_CNF;
/*
* We are sending result code
* eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA which
* will trigger proper cleanup (DEL_STA/DEL_BSS both
* required) in either assoc cnf or reassoc cnf handler.
*/
mlm_assoc_cnf.resultCode =
eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA;
mlm_assoc_cnf.protStatusCode =
eSIR_MAC_UNSPEC_FAILURE_STATUS;
session_entry->staId = add_sta_params->staIdx;
goto end;
}
}
if (QDF_STATUS_SUCCESS == add_sta_params->status) {
if (eLIM_MLM_WT_ADD_STA_RSP_STATE !=
session_entry->limMlmState) {
lim_log(mac_ctx, LOGE,
FL("Received WMA_ADD_STA_RSP in state %X"),
session_entry->limMlmState);
mlm_assoc_cnf.resultCode =
(tSirResultCodes) eSIR_SME_REFUSED;
goto end;
}
if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) {
/* check if we have keys(PTK)to install in case of 11r */
tpftPEContext ft_ctx = &session_entry->ftPEContext;
ft_session = pe_find_session_by_bssid(mac_ctx,
session_entry->limReAssocbssId, &ft_session_id);
if (ft_session != NULL &&
ft_ctx->PreAuthKeyInfo.extSetStaKeyParamValid
== true) {
tpLimMlmSetKeysReq pMlmStaKeys =
&ft_ctx->PreAuthKeyInfo.extSetStaKeyParam;
lim_send_set_sta_key_req(mac_ctx, pMlmStaKeys,
0, 0, ft_session, false);
ft_ctx->PreAuthKeyInfo.extSetStaKeyParamValid =
false;
}
}
/*
* Update the DPH Hash Entry for this STA
* with proper state info
*/
sta_ds =
dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
&session_entry->dph.dphHashTable);
if (NULL != sta_ds) {
sta_ds->mlmStaContext.mlmState =
eLIM_MLM_LINK_ESTABLISHED_STATE;
sta_ds->nss = add_sta_params->nss;
} else
lim_log(mac_ctx, LOGW,
FL("Fail to get DPH Hash Entry for AID - %d"),
DPH_STA_HASH_INDEX_PEER);
session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
session_entry->peSessionId,
session_entry->limMlmState));
/*
* Storing the self StaIndex(Generated by HAL) in
* session context, instead of storing it in DPH Hash
* entry for Self STA.
* DPH entry for the self STA stores the sta index for
* the BSS entry to which the STA is associated
*/
session_entry->staId = add_sta_params->staIdx;
#ifdef WLAN_DEBUG
mac_ctx->lim.gLimNumLinkEsts++;
#endif
#ifdef FEATURE_WLAN_TDLS
/* initialize TDLS peer related data */
lim_init_tdls_data(mac_ctx, session_entry);
#endif
/*
* Return Assoc confirm to SME with success
* FIXME - Need the correct ASSOC RSP code to
* be passed in here
*/
mlm_assoc_cnf.resultCode = (tSirResultCodes) eSIR_SME_SUCCESS;
} else {
lim_log(mac_ctx, LOGE, FL("ADD_STA failed!"));
if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
mlm_assoc_cnf.resultCode =
(tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE;
else
mlm_assoc_cnf.resultCode =
(tSirResultCodes) eSIR_SME_REFUSED;
mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
}
end:
if (NULL != msg->bodyptr) {
qdf_mem_free(add_sta_params);
msg->bodyptr = NULL;
}
/* Updating PE session Id */
mlm_assoc_cnf.sessionId = session_entry->peSessionId;
lim_post_sme_message(mac_ctx, msg_type, (uint32_t *) &mlm_assoc_cnf);
if (true == session_entry->fDeauthReceived)
session_entry->fDeauthReceived = false;
return;
}
void lim_process_mlm_del_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
tpPESession psessionEntry)
{
/* we need to process the deferred message since the initiating req. there might be nested request. */
/* in the case of nested request the new request initiated from the response will take care of resetting */
/* the deffered flag. */
SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
pMac->sys.gSysFrameCount[SIR_MAC_MGMT_FRAME][SIR_MAC_MGMT_DEAUTH] = 0;
if (LIM_IS_AP_ROLE(psessionEntry) &&
(psessionEntry->statypeForBss == STA_ENTRY_SELF)) {
lim_process_ap_mlm_del_bss_rsp(pMac, limMsgQ, psessionEntry);
return;
}
lim_process_sta_mlm_del_bss_rsp(pMac, limMsgQ, psessionEntry);
#ifdef WLAN_FEATURE_11W
if (psessionEntry->limRmfEnabled) {
if (eSIR_SUCCESS !=
lim_send_exclude_unencrypt_ind(pMac, true, psessionEntry)) {
lim_log(pMac, LOGE,
FL
("Could not send down Exclude Unencrypted Indication!"));
}
}
#endif
}
void lim_process_sta_mlm_del_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
tpPESession psessionEntry)
{
tpDeleteBssParams pDelBssParams = (tpDeleteBssParams) limMsgQ->bodyptr;
tpDphHashNode pStaDs =
dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
&psessionEntry->dph.dphHashTable);
tSirResultCodes statusCode = eSIR_SME_SUCCESS;
if (NULL == pDelBssParams) {
lim_log(pMac, LOGE, FL("Invalid body pointer in message"));
goto end;
}
if (QDF_STATUS_SUCCESS == pDelBssParams->status) {
PELOGW(lim_log(pMac, LOGW,
FL("STA received the DEL_BSS_RSP for BSSID: %X."),
pDelBssParams->bssIdx);
)
if (lim_set_link_state
(pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId,
psessionEntry->selfMacAddr, NULL,
NULL) != eSIR_SUCCESS) {
PELOGE(lim_log
(pMac, LOGE,
FL("Failure in setting link state to IDLE"));
)
statusCode = eSIR_SME_REFUSED;
goto end;
}
if (pStaDs == NULL) {
lim_log(pMac, LOGE, FL("DPH Entry for STA 1 missing."));
statusCode = eSIR_SME_REFUSED;
goto end;
}
if (eLIM_MLM_WT_DEL_BSS_RSP_STATE !=
pStaDs->mlmStaContext.mlmState) {
PELOGE(lim_log
(pMac, LOGE,
FL
("Received unexpected WMA_DEL_BSS_RSP in state %X"),
pStaDs->mlmStaContext.mlmState);
)
statusCode = eSIR_SME_REFUSED;
goto end;
}
PELOG1(lim_log
(pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId);
lim_print_mac_addr(pMac, pStaDs->staAddr, LOG1);
)
} else {
lim_log(pMac, LOGE, FL("DEL BSS failed!"));
statusCode = eSIR_SME_STOP_BSS_FAILURE;
}
end:
if (0 != limMsgQ->bodyptr) {
qdf_mem_free(pDelBssParams);
limMsgQ->bodyptr = NULL;
}
if (pStaDs == NULL)
return;
if ((LIM_IS_STA_ROLE(psessionEntry)) &&
(psessionEntry->limSmeState !=
eLIM_SME_WT_DISASSOC_STATE &&
psessionEntry->limSmeState !=
eLIM_SME_WT_DEAUTH_STATE) &&
pStaDs->mlmStaContext.cleanupTrigger !=
eLIM_JOIN_FAILURE) {
/** The Case where the DelBss is invoked from
* context of other than normal DisAssoc / Deauth OR
* as part of Join Failure.
*/
lim_handle_del_bss_in_re_assoc_context(pMac, pStaDs, psessionEntry);
return;
}
lim_prepare_and_send_del_sta_cnf(pMac, pStaDs, statusCode, psessionEntry);
return;
}
void lim_process_ap_mlm_del_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
tpPESession psessionEntry)
{
tSirResultCodes rc = eSIR_SME_SUCCESS;
tSirRetStatus status;
tpDeleteBssParams pDelBss = (tpDeleteBssParams) limMsgQ->bodyptr;
tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
if (psessionEntry == NULL) {
lim_log(pMac, LOGE, FL("Session entry passed is NULL"));
if (pDelBss != NULL) {
qdf_mem_free(pDelBss);
limMsgQ->bodyptr = NULL;
}
return;
}
if (pDelBss == NULL) {
PELOGE(lim_log(pMac, LOGE, FL("BSS: DEL_BSS_RSP with no body!"));)
rc = eSIR_SME_REFUSED;
goto end;
}
pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
MTRACE(mac_trace
(pMac, TRACE_CODE_MLM_STATE, NO_SESSION,
pMac->lim.gLimMlmState));
if (eLIM_MLM_WT_DEL_BSS_RSP_STATE != psessionEntry->limMlmState) {
lim_log(pMac, LOGE,
FL("Received unexpected WMA_DEL_BSS_RSP in state %X"),
psessionEntry->limMlmState);
rc = eSIR_SME_REFUSED;
goto end;
}
if (pDelBss->status != QDF_STATUS_SUCCESS) {
lim_log(pMac, LOGE, FL("BSS: DEL_BSS_RSP error (%x) Bss %d "),
pDelBss->status, pDelBss->bssIdx);
rc = eSIR_SME_STOP_BSS_FAILURE;
goto end;
}
status = lim_set_link_state(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
psessionEntry->selfMacAddr, NULL, NULL);
if (status != eSIR_SUCCESS) {
rc = eSIR_SME_REFUSED;
goto end;
}
/** Softmac may send all the buffered packets right after resuming the transmission hence
* to occupy the medium during non channel occupancy period. So resume the transmission after
* HAL gives back the response.
*/
dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
lim_delete_pre_auth_list(pMac);
/* Initialize number of associated stations during cleanup */
psessionEntry->gLimNumOfCurrentSTAs = 0;
end:
lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,
psessionEntry->smeSessionId,
psessionEntry->transactionId);
pe_delete_session(pMac, psessionEntry);
if (pDelBss != NULL) {
qdf_mem_free(pDelBss);
limMsgQ->bodyptr = NULL;
}
}
/**
* lim_process_mlm_del_sta_rsp() - Process DEL STA response
* @mac_ctx: Pointer to Global MAC structure
* @msg: The MsgQ header, which contains the response buffer
*
* This function is called to process a WMA_DEL_STA_RSP from
* WMA Upon receipt of this message from FW.
*
* Return: None
*/
void lim_process_mlm_del_sta_rsp(tpAniSirGlobal mac_ctx,
tpSirMsgQ msg)
{
/*
* we need to process the deferred message since the
* initiating req. there might be nested request
* in the case of nested request the new request
* initiated from the response will take care of resetting
* the deffered flag.
*/
tpPESession session_entry;
tpDeleteStaParams del_sta_params;
del_sta_params = (tpDeleteStaParams) msg->bodyptr;
if (NULL == del_sta_params) {
lim_log(mac_ctx, LOGE,
FL("null pointer del_sta_params msg"));
return;
}
SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
session_entry = pe_find_session_by_session_id(mac_ctx,
del_sta_params->sessionId);
if (NULL == session_entry) {
lim_log(mac_ctx, LOGP, FL("Session Doesn't exist: %d"),
del_sta_params->sessionId);
qdf_mem_free(del_sta_params);
msg->bodyptr = NULL;
return;
}
if (LIM_IS_AP_ROLE(session_entry)) {
lim_process_ap_mlm_del_sta_rsp(mac_ctx, msg,
session_entry);
return;
}
if (LIM_IS_NDI_ROLE(session_entry)) {
lim_process_ndi_del_sta_rsp(mac_ctx, msg, session_entry);
return;
}
lim_process_sta_mlm_del_sta_rsp(mac_ctx, msg, session_entry);
}
/**
* lim_process_ap_mlm_del_sta_rsp() - Process WMA_DEL_STA_RSP
* @mac_ctx: Global pointer to MAC context
* @msg: Received message
* @session_entry: Session entry
*
* Process WMA_DEL_STA_RSP for AP role
*
* Retunrn: None
*/
void lim_process_ap_mlm_del_sta_rsp(tpAniSirGlobal mac_ctx,
tpSirMsgQ msg,
tpPESession session_entry)
{
tpDeleteStaParams del_sta_params = (tpDeleteStaParams) msg->bodyptr;
tpDphHashNode sta_ds;
tSirResultCodes status_code = eSIR_SME_SUCCESS;
if (msg->bodyptr == NULL) {
lim_log(mac_ctx, LOGE, FL("msg->bodyptr NULL"));
return;
}
sta_ds = dph_get_hash_entry(mac_ctx, del_sta_params->assocId,
&session_entry->dph.dphHashTable);
if (sta_ds == NULL) {
lim_log(mac_ctx, LOGE, FL("DPH Entry for STA %X missing."),
del_sta_params->assocId);
status_code = eSIR_SME_REFUSED;
qdf_mem_free(del_sta_params);
msg->bodyptr = NULL;
return;
}
lim_log(mac_ctx, LOG1, FL("Received del Sta Rsp in StaD MlmState : %d"),
sta_ds->mlmStaContext.mlmState);
if (QDF_STATUS_SUCCESS != del_sta_params->status) {
lim_log(mac_ctx, LOGW, FL("DEL STA failed!"));
status_code = eSIR_SME_REFUSED;
goto end;
}
lim_log(mac_ctx, LOGW,
FL("AP received the DEL_STA_RSP for assocID: %X."),
del_sta_params->assocId);
if ((eLIM_MLM_WT_DEL_STA_RSP_STATE != sta_ds->mlmStaContext.mlmState) &&
(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
sta_ds->mlmStaContext.mlmState)) {
lim_log(mac_ctx, LOGE,
FL("Received unexpected WMA_DEL_STA_RSP in state %s for staId %d assocId %d "),
lim_mlm_state_str(sta_ds->mlmStaContext.mlmState),
sta_ds->staIndex, sta_ds->assocId);
status_code = eSIR_SME_REFUSED;
goto end;
}
lim_log(mac_ctx, LOG1, FL("Deleted STA AssocID %d staId %d MAC "),
sta_ds->assocId, sta_ds->staIndex);
lim_print_mac_addr(mac_ctx, sta_ds->staAddr, LOG1);
if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE ==
sta_ds->mlmStaContext.mlmState) {
qdf_mem_free(del_sta_params);
msg->bodyptr = NULL;
if (lim_add_sta(mac_ctx, sta_ds, false, session_entry) !=
eSIR_SUCCESS) {
lim_log(mac_ctx, LOGE, FL("could not Add STA with assocId=%d"),
sta_ds->assocId);
/*
* delete the TS if it has already been added.
* send the response with error status.
*/
if (sta_ds->qos.addtsPresent) {
tpLimTspecInfo pTspecInfo;
if (eSIR_SUCCESS ==
lim_tspec_find_by_assoc_id(mac_ctx,
sta_ds->assocId,
&sta_ds->qos.addts.tspec,
&mac_ctx->lim.tspecInfo[0],
&pTspecInfo)) {
lim_admit_control_delete_ts(mac_ctx,
sta_ds->assocId,
&sta_ds->qos.addts.tspec.tsinfo,
NULL,
&pTspecInfo->idx);
}
}
lim_reject_association(mac_ctx, sta_ds->staAddr,
sta_ds->mlmStaContext.subType, true,
sta_ds->mlmStaContext.authType, sta_ds->assocId,
true,
(tSirResultCodes)eSIR_MAC_UNSPEC_FAILURE_STATUS,
session_entry);
}
return;
}
end:
qdf_mem_free(del_sta_params);
msg->bodyptr = NULL;
if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
sta_ds->mlmStaContext.mlmState) {
lim_prepare_and_send_del_sta_cnf(mac_ctx, sta_ds, status_code,
session_entry);
}
return;
}
void lim_process_sta_mlm_del_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
tpPESession psessionEntry)
{
tSirResultCodes statusCode = eSIR_SME_SUCCESS;
tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
tpDphHashNode pStaDs = NULL;
if (NULL == pDelStaParams) {
lim_log(pMac, LOGE, FL("Encountered NULL Pointer"));
goto end;
}
lim_log(pMac, LOG1, FL("Del STA RSP received. Status:%d AssocID:%d"),
pDelStaParams->status, pDelStaParams->assocId);
if (QDF_STATUS_SUCCESS != pDelStaParams->status)
lim_log(pMac, LOGE, FL(
"Del STA failed! Status:%d, proceeding with Del BSS"),
pDelStaParams->status);
pStaDs = dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
&psessionEntry->dph.dphHashTable);
if (pStaDs == NULL) {
lim_log(pMac, LOGE, FL("DPH Entry for STA %X missing."),
pDelStaParams->assocId);
statusCode = eSIR_SME_REFUSED;
goto end;
}
if (eLIM_MLM_WT_DEL_STA_RSP_STATE != psessionEntry->limMlmState) {
lim_log(pMac, LOGE, FL(
"Received unexpected WDA_DELETE_STA_RSP in state %s"),
lim_mlm_state_str(psessionEntry->limMlmState));
statusCode = eSIR_SME_REFUSED;
goto end;
}
lim_log(pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId);
lim_print_mac_addr(pMac, pStaDs->staAddr, LOG1);
/*
* we must complete all cleanup related to delSta before
* calling limDelBSS.
*/
if (0 != limMsgQ->bodyptr) {
qdf_mem_free(pDelStaParams);
limMsgQ->bodyptr = NULL;
}
/* Proceed to do DelBSS even if DelSta resulted in failure */
statusCode = (tSirResultCodes)lim_del_bss(pMac, pStaDs, 0,
psessionEntry);
return;
end:
if (0 != limMsgQ->bodyptr) {
qdf_mem_free(pDelStaParams);
limMsgQ->bodyptr = NULL;
}
return;
}
void lim_process_ap_mlm_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
tpPESession psessionEntry)
{
tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
tpDphHashNode pStaDs = NULL;
if (NULL == pAddStaParams) {
lim_log(pMac, LOGE, FL("Invalid body pointer in message"));
goto end;
}
pStaDs =
dph_get_hash_entry(pMac, pAddStaParams->assocId,
&psessionEntry->dph.dphHashTable);
if (pStaDs == NULL) {
/* TODO: any response to be sent out here ? */
lim_log(pMac, LOGE, FL("DPH Entry for STA %X missing."),
pAddStaParams->assocId);
goto end;
}
/* */
/* TODO & FIXME_GEN4 */
/* Need to inspect tSirMsgQ.reserved for a valid Dialog token! */
/* */
/* TODO: any check for pMac->lim.gLimMlmState ? */
if (eLIM_MLM_WT_ADD_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) {
/* TODO: any response to be sent out here ? */
lim_log(pMac, LOGE,
FL("Received unexpected WMA_ADD_STA_RSP in state %X"),
pStaDs->mlmStaContext.mlmState);
goto end;
}
if (QDF_STATUS_SUCCESS != pAddStaParams->status) {
PELOGE(lim_log
(pMac, LOGE,
FL("Error! rcvd delSta rsp from HAL with status %d"),
pAddStaParams->status);
)
lim_reject_association(pMac, pStaDs->staAddr,
pStaDs->mlmStaContext.subType,
true, pStaDs->mlmStaContext.authType,
pStaDs->assocId, true,
(tSirResultCodes)
eSIR_MAC_UNSPEC_FAILURE_STATUS,
psessionEntry);
goto end;
}
pStaDs->bssId = pAddStaParams->bssIdx;
pStaDs->staIndex = pAddStaParams->staIdx;
pStaDs->nss = pAddStaParams->nss;
/* if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state */
pStaDs->valid = 1;
pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE;
lim_log(pMac, LOG1,
FL("AddStaRsp Success.STA AssocID %d staId %d MAC "),
pStaDs->assocId, pStaDs->staIndex);
lim_print_mac_addr(pMac, pStaDs->staAddr, LOG1);
/* For BTAMP-AP, the flow sequence shall be:
* 1) PE sends eWNI_SME_ASSOC_IND to SME
* 2) PE receives eWNI_SME_ASSOC_CNF from SME
* 3) BTAMP-AP sends Re/Association Response to BTAMP-STA
*/
lim_send_mlm_assoc_ind(pMac, pStaDs, psessionEntry);
/* fall though to reclaim the original Add STA Response message */
end:
if (0 != limMsgQ->bodyptr) {
qdf_mem_free(pAddStaParams);
limMsgQ->bodyptr = NULL;
}
return;
}
/**
* lim_process_ap_mlm_add_bss_rsp()
*
***FUNCTION:
* This function is called to process a WMA_ADD_BSS_RSP from HAL.
* Upon receipt of this message from HAL, MLME -
* > Validates the result of WMA_ADD_BSS_REQ
* > Init other remaining LIM variables
* > Init the AID pool, for that BSSID
* > Init the Pre-AUTH list, for that BSSID
* > Create LIM timers, specific to that BSSID
* > Init DPH related parameters that are specific to that BSSID
* > TODO - When do we do the actual change channel?
*
***LOGIC:
* SME sends eWNI_SME_START_BSS_REQ to LIM
* LIM sends LIM_MLM_START_REQ to MLME
* MLME sends WMA_ADD_BSS_REQ to HAL
* HAL responds with WMA_ADD_BSS_RSP to MLME
* MLME responds with LIM_MLM_START_CNF to LIM
* LIM responds with eWNI_SME_START_BSS_RSP to SME
*
***ASSUMPTIONS:
* tSirMsgQ.body is allocated by MLME during lim_process_mlm_start_req
* tSirMsgQ.body will now be freed by this routine
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param tSirMsgQ The MsgQ header, which contains the response buffer
*
* @return None
*/
static void lim_process_ap_mlm_add_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ)
{
tLimMlmStartCnf mlmStartCnf;
tpPESession psessionEntry;
uint8_t isWepEnabled = false;
tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
if (NULL == pAddBssParams) {
lim_log(pMac, LOGE, FL("Encountered NULL Pointer"));
goto end;
}
/* TBD: free the memory before returning, do it for all places where lookup fails. */
psessionEntry = pe_find_session_by_session_id(pMac,
pAddBssParams->sessionId);
if (psessionEntry == NULL) {
PELOGE(lim_log
(pMac, LOGE,
FL("session does not exist for given sessionId"));
)
if (NULL != pAddBssParams) {
qdf_mem_free(pAddBssParams);
limMsgQ->bodyptr = NULL;
}
return;
}
/* Update PE session Id */
mlmStartCnf.sessionId = pAddBssParams->sessionId;
if (QDF_STATUS_SUCCESS == pAddBssParams->status) {
PELOG2(lim_log
(pMac, LOG2,
FL("WMA_ADD_BSS_RSP returned with QDF_STATUS_SUCCESS"));
)
if (lim_set_link_state
(pMac, eSIR_LINK_AP_STATE, psessionEntry->bssId,
psessionEntry->selfMacAddr, NULL,
NULL) != eSIR_SUCCESS)
goto end;
/* Set MLME state */
psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
psessionEntry->chainMask = pAddBssParams->chainMask;
psessionEntry->smpsMode = pAddBssParams->smpsMode;
MTRACE(mac_trace
(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
psessionEntry->limMlmState));
if (eSIR_IBSS_MODE == pAddBssParams->bssType) {
/** IBSS is 'active' when we receive
* Beacon frames from other STAs that are part of same IBSS.
* Mark internal state as inactive until then.
*/
psessionEntry->limIbssActive = false;
psessionEntry->statypeForBss = STA_ENTRY_PEER; /* to know session created for self/peer */
limResetHBPktCount(psessionEntry);
}
psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
if (eSIR_INFRA_AP_MODE == pAddBssParams->bssType)
psessionEntry->limSystemRole = eLIM_AP_ROLE;
else
psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
sch_edca_profile_update(pMac, psessionEntry);
lim_init_pre_auth_list(pMac);
/* Check the SAP security configuration.If configured to
* WEP then max clients supported is 16
*/
if (psessionEntry->privacy) {
if ((psessionEntry->gStartBssRSNIe.present)
|| (psessionEntry->gStartBssWPAIe.present))
lim_log(pMac, LOG1,
FL("WPA/WPA2 SAP configuration"));
else {
if (pMac->lim.gLimAssocStaLimit >
MAX_SUPPORTED_PEERS_WEP) {
lim_log(pMac, LOG1,
FL("WEP SAP Configuration"));
pMac->lim.gLimAssocStaLimit =
MAX_SUPPORTED_PEERS_WEP;
isWepEnabled = true;
}
}
}
lim_init_peer_idxpool(pMac, psessionEntry);
/* Start OLBC timer */
if (tx_timer_activate
(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer) !=
TX_SUCCESS) {
lim_log(pMac, LOGE, FL("tx_timer_activate failed"));
}
/* Apply previously set configuration at HW */
lim_apply_configuration(pMac, psessionEntry);
/* In lim_apply_configuration gLimAssocStaLimit is assigned from cfg.
* So update the value to 16 in case SoftAP is configured in WEP.
*/
if ((pMac->lim.gLimAssocStaLimit > MAX_SUPPORTED_PEERS_WEP)
&& (isWepEnabled))
pMac->lim.gLimAssocStaLimit = MAX_SUPPORTED_PEERS_WEP;
psessionEntry->staId = pAddBssParams->staContext.staIdx;
mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
} else {
lim_log(pMac, LOGE, FL("WMA_ADD_BSS_REQ failed with status %d"),
pAddBssParams->status);
mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
}
lim_post_sme_message(pMac, LIM_MLM_START_CNF, (uint32_t *) &mlmStartCnf);
end:
if (0 != limMsgQ->bodyptr) {
qdf_mem_free(pAddBssParams);
limMsgQ->bodyptr = NULL;
}
}
/**
* lim_process_ibss_mlm_add_bss_rsp()
*
***FUNCTION:
* This function is called to process a WMA_ADD_BSS_RSP from HAL.
* Upon receipt of this message from HAL, MLME -
* > Validates the result of WMA_ADD_BSS_REQ
* > Init other remaining LIM variables
* > Init the AID pool, for that BSSID
* > Init the Pre-AUTH list, for that BSSID
* > Create LIM timers, specific to that BSSID
* > Init DPH related parameters that are specific to that BSSID
* > TODO - When do we do the actual change channel?
*
***LOGIC:
* SME sends eWNI_SME_START_BSS_REQ to LIM
* LIM sends LIM_MLM_START_REQ to MLME
* MLME sends WMA_ADD_BSS_REQ to HAL
* HAL responds with WMA_ADD_BSS_RSP to MLME
* MLME responds with LIM_MLM_START_CNF to LIM
* LIM responds with eWNI_SME_START_BSS_RSP to SME
*
***ASSUMPTIONS:
* tSirMsgQ.body is allocated by MLME during lim_process_mlm_start_req
* tSirMsgQ.body will now be freed by this routine
*
***NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param tSirMsgQ The MsgQ header, which contains the response buffer
*
* @return None
*/
static void
lim_process_ibss_mlm_add_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
tpPESession psessionEntry)
{
tLimMlmStartCnf mlmStartCnf;
tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
if (NULL == pAddBssParams) {
lim_log(pMac, LOGE, FL("Invalid body pointer in message"));
goto end;
}
if (QDF_STATUS_SUCCESS == pAddBssParams->status) {
PELOG1(lim_log
(pMac, LOG1,
FL("WMA_ADD_BSS_RSP returned with QDF_STATUS_SUCCESS"));
)
if (lim_set_link_state
(pMac, eSIR_LINK_IBSS_STATE, psessionEntry->bssId,
psessionEntry->selfMacAddr, NULL,
NULL) != eSIR_SUCCESS)
goto end;
/* Set MLME state */
psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
MTRACE(mac_trace
(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
psessionEntry->limMlmState));
/** IBSS is 'active' when we receive
* Beacon frames from other STAs that are part of same IBSS.
* Mark internal state as inactive until then.
*/
psessionEntry->limIbssActive = false;
limResetHBPktCount(psessionEntry);
psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
psessionEntry->statypeForBss = STA_ENTRY_SELF;
sch_edca_profile_update(pMac, psessionEntry);
if (0 == psessionEntry->freePeerIdxHead)
lim_init_peer_idxpool(pMac, psessionEntry);
/* Apply previously set configuration at HW */
lim_apply_configuration(pMac, psessionEntry);
psessionEntry->staId = pAddBssParams->staContext.staIdx;
mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
/* If ADD BSS was issued as part of IBSS coalescing, don't send the message to SME, as that is internal to LIM */
if (true == pMac->lim.gLimIbssCoalescingHappened) {
lim_ibss_add_bss_rsp_when_coalescing(pMac, limMsgQ->bodyptr,
psessionEntry);
goto end;
}
} else {
lim_log(pMac, LOGE, FL("WMA_ADD_BSS_REQ failed with status %d"),
pAddBssParams->status);
mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
}
/* Send this message to SME, when ADD_BSS is initiated by SME */
/* If ADD_BSS is done as part of coalescing, this won't happen. */
/* Update PE session Id */
mlmStartCnf.sessionId = psessionEntry->peSessionId;
lim_post_sme_message(pMac, LIM_MLM_START_CNF, (uint32_t *) &mlmStartCnf);
end:
if (0 != limMsgQ->bodyptr) {
qdf_mem_free(pAddBssParams);
limMsgQ->bodyptr = NULL;
}
}
/**
* csr_neighbor_roam_handoff_req_hdlr - Processes handoff request
* @mac_ctx: Pointer to mac context
* @msg: message sent to HDD
* @session_entry: PE session handle
*
* This function is called to process a WMA_ADD_BSS_RSP from HAL.
* Upon receipt of this message from HAL if the state is pre assoc.
*
* Return: Null
*/
static void
lim_process_sta_add_bss_rsp_pre_assoc(tpAniSirGlobal mac_ctx,
tpSirMsgQ msg, tpPESession session_entry)
{
tpAddBssParams pAddBssParams = (tpAddBssParams) msg->bodyptr;
tAniAuthType cfgAuthType, authMode;
tLimMlmAuthReq *pMlmAuthReq;
tpDphHashNode pStaDs = NULL;
if (NULL == pAddBssParams) {
lim_log(mac_ctx, LOGE, FL("Invalid body pointer in message"));
goto joinFailure;
}
if (QDF_STATUS_SUCCESS == pAddBssParams->status) {
pStaDs = dph_add_hash_entry(mac_ctx,
pAddBssParams->staContext.staMac,
DPH_STA_HASH_INDEX_PEER,
&session_entry->dph.dphHashTable);
if (pStaDs == NULL) {
/* Could not add hash table entry */
lim_log(mac_ctx, LOGE,
FL("could not add hash entry at DPH for "));
lim_print_mac_addr(mac_ctx,
pAddBssParams->staContext.staMac, LOGE);
goto joinFailure;
}
session_entry->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;
/* Trigger Authentication with AP */
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_AUTHENTICATION_TYPE,
(uint32_t *) &cfgAuthType) != eSIR_SUCCESS) {
/*
* Could not get AuthType from CFG.
* Log error.
*/
lim_log(mac_ctx, LOGP,
FL("could not retrieve AuthType"));
}
/* Try shared Authentication first */
if (cfgAuthType == eSIR_AUTO_SWITCH)
authMode = eSIR_SHARED_KEY;
else
authMode = cfgAuthType;
/* Trigger MAC based Authentication */
pMlmAuthReq = qdf_mem_malloc(sizeof(tLimMlmAuthReq));
if (NULL == pMlmAuthReq) {
lim_log(mac_ctx, LOGP,
FL("Allocate Memory failed for mlmAuthReq"));
return;
}
sir_copy_mac_addr(pMlmAuthReq->peerMacAddr,
session_entry->bssId);
pMlmAuthReq->authType = authMode;
if (wlan_cfg_get_int(mac_ctx,
WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
(uint32_t *) &pMlmAuthReq->authFailureTimeout)
!= eSIR_SUCCESS) {
/*
* Could not get AuthFailureTimeout
* value from CFG. Log error.
*/
lim_log(mac_ctx, LOGP,
FL("Fail: retrieve AuthFailureTimeout value"));
}
session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
session_entry->peSessionId, eLIM_MLM_JOINED_STATE));
pMlmAuthReq->sessionId = session_entry->peSessionId;
session_entry->limPrevSmeState = session_entry->limSmeState;
session_entry->limSmeState = eLIM_SME_WT_AUTH_STATE;
/* remember staId in case of assoc timeout/failure handling */
session_entry->staId = pAddBssParams->staContext.staIdx;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
lim_log(mac_ctx, LOG1,
FL("SessionId:%d lim_post_mlm_message "
"LIM_MLM_AUTH_REQ with limSmeState:%d"),
session_entry->peSessionId, session_entry->limSmeState);
lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ,
(uint32_t *) pMlmAuthReq);
return;
}
joinFailure:
{
session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
session_entry->peSessionId,
session_entry->limSmeState));
/* Send Join response to Host */
lim_handle_sme_join_result(mac_ctx, eSIR_SME_REFUSED,
eSIR_MAC_UNSPEC_FAILURE_STATUS, session_entry);
}
}
/**
* lim_process_sta_mlm_add_bss_rsp() - Process ADD BSS response
* @mac_ctx: Pointer to Global MAC structure
* @msg: The MsgQ header, which contains the response buffer
*
* This function is called to process a WMA_ADD_BSS_RSP from HAL.
* Upon receipt of this message from HAL, MLME -
* > Validates the result of WMA_ADD_BSS_REQ
* > Now, send an ADD_STA to HAL and ADD the "local" STA itself
*
* MLME had sent WMA_ADD_BSS_REQ to HAL
* HAL responded with WMA_ADD_BSS_RSP to MLME
* MLME now sends WMA_ADD_STA_REQ to HAL
* ASSUMPTIONS:
* tSirMsgQ.body is allocated by MLME during lim_process_mlm_join_req
* tSirMsgQ.body will now be freed by this routine
*
* Return: None
*/
static void
lim_process_sta_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
tpSirMsgQ msg, tpPESession session_entry)
{
tpAddBssParams add_bss_params = (tpAddBssParams) msg->bodyptr;
tLimMlmAssocCnf mlm_assoc_cnf;
uint32_t msg_type = LIM_MLM_ASSOC_CNF;
uint32_t sub_type = LIM_ASSOC;
tpDphHashNode sta_ds = NULL;
uint16_t sta_idx = STA_INVALID_IDX;
uint8_t update_sta = false;
mlm_assoc_cnf.resultCode = eSIR_SME_SUCCESS;
if (eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE ==
session_entry->limMlmState) {
lim_log(mac_ctx, LOG1,
"SessionId:%d lim_process_sta_add_bss_rsp_pre_assoc",
session_entry->peSessionId);
lim_process_sta_add_bss_rsp_pre_assoc(mac_ctx, msg,
session_entry);
goto end;
}
if (eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == session_entry->limMlmState
|| (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
session_entry->limMlmState)) {
msg_type = LIM_MLM_REASSOC_CNF;
sub_type = LIM_REASSOC;
/*
* If Reassoc is happening for the same BSS, then
* use the existing StaId and indicate to HAL to update
* the existing STA entry.
* If Reassoc is happening for the new BSS, then
* old BSS and STA entry would have been already deleted
* before PE tries to add BSS for the new BSS, so set the
* updateSta to false and pass INVALID STA Index.
*/
if (sir_compare_mac_addr(session_entry->bssId,
session_entry->limReAssocbssId)) {
sta_idx = session_entry->staId;
update_sta = true;
}
}
if (add_bss_params == 0)
goto end;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
if (session_entry->bRoamSynchInProgress)
QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
"LFR3:lim_process_sta_mlm_add_bss_rsp");
#endif
if (QDF_STATUS_SUCCESS == add_bss_params->status) {
if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
session_entry->limMlmState) {
lim_log(mac_ctx, LOG1, FL("Mlm=%d %d"),
session_entry->limMlmState,
eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
lim_process_sta_mlm_add_bss_rsp_ft(mac_ctx, msg,
session_entry);
goto end;
}
/* Set MLME state */
session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
session_entry->peSessionId,
session_entry->limMlmState));
/* to know the session started for self or for peer */
session_entry->statypeForBss = STA_ENTRY_PEER;
/* Now, send WMA_ADD_STA_REQ */
lim_log(mac_ctx, LOGW,
FL("SessionId:%d On STA: ADD_BSS was successful"),
session_entry->peSessionId);
sta_ds =
dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
&session_entry->dph.dphHashTable);
if (sta_ds == NULL) {
lim_log(mac_ctx, LOGE,
FL("Session:%d Fail to add Self Entry for STA"),
session_entry->peSessionId);
mlm_assoc_cnf.resultCode =
(tSirResultCodes) eSIR_SME_REFUSED;
} else {
session_entry->bssIdx =
(uint8_t) add_bss_params->bssIdx;
/* Success, handle below */
sta_ds->bssId = add_bss_params->bssIdx;
/*
* STA Index(genr by HAL) for the BSS
* entry is stored here
*/
sta_ds->staIndex = add_bss_params->staContext.staIdx;
sta_ds->ucUcastSig =
add_bss_params->staContext.ucUcastSig;
sta_ds->ucBcastSig =
add_bss_params->staContext.ucBcastSig;
/* Downgrade the EDCA parameters if needed */
lim_set_active_edca_params(mac_ctx,
session_entry->gLimEdcaParams, session_entry);
lim_send_edca_params(mac_ctx,
session_entry->gLimEdcaParamsActive,
sta_ds->bssId);
rrm_cache_mgmt_tx_power(mac_ctx,
add_bss_params->txMgmtPower, session_entry);
if (lim_add_sta_self(mac_ctx, sta_idx, update_sta,
session_entry) != eSIR_SUCCESS) {
/* Add STA context at HW */
lim_log(mac_ctx, LOGE,
FL("Session:%d could not Add Self"
"Entry for the station"),
session_entry->peSessionId);
mlm_assoc_cnf.resultCode =
(tSirResultCodes) eSIR_SME_REFUSED;
}
}
} else {
lim_log(mac_ctx, LOGP, FL("SessionId:%d ADD_BSS failed!"),
session_entry->peSessionId);
mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
/* Return Assoc confirm to SME with failure */
if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
session_entry->limMlmState)
mlm_assoc_cnf.resultCode =
(tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE;
else
mlm_assoc_cnf.resultCode =
(tSirResultCodes) eSIR_SME_REFUSED;
session_entry->add_bss_failed = true;
}
if (mlm_assoc_cnf.resultCode != eSIR_SME_SUCCESS) {
session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE,
session_entry->bssId,
session_entry->selfMacAddr,
NULL, NULL) != eSIR_SUCCESS)
lim_log(mac_ctx, LOGE, FL("Failed to set the LinkState"));
/* Update PE session Id */
mlm_assoc_cnf.sessionId = session_entry->peSessionId;
lim_post_sme_message(mac_ctx, msg_type,
(uint32_t *) &mlm_assoc_cnf);
}
end:
if (0 != msg->bodyptr) {
qdf_mem_free(add_bss_params);
msg->bodyptr = NULL;
}
}
/**
* lim_process_mlm_add_bss_rsp() - Processes ADD BSS Response
*
* @mac_ctx - Pointer to Global MAC structure
* @msg - The MsgQ header, which contains the response buffer
*
* This function is called to process a WMA_ADD_BSS_RSP from HAL.
* Upon receipt of this message from HAL, MLME -
* Determines the "state" in which this message was received
* Forwards it to the appropriate callback
*
*LOGIC:
* WMA_ADD_BSS_RSP can be received by MLME while the LIM is
* in the following two states:
* 1) As AP, LIM state = eLIM_SME_WT_START_BSS_STATE
* 2) As STA, LIM state = eLIM_SME_WT_JOIN_STATE
* Based on these two states, this API will determine where to
* route the message to
*
* Return None
*/
void lim_process_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
tpSirMsgQ msg)
{
tLimMlmStartCnf mlm_start_cnf;
tpPESession session_entry;
tpAddBssParams add_bss_param = (tpAddBssParams) (msg->bodyptr);
tSirBssType bss_type;
if (NULL == add_bss_param) {
lim_log(mac_ctx, LOGE, FL("Encountered NULL Pointer"));
return;
}
/*
* we need to process the deferred message since the
* initiating req.there might be nested request.
* in the case of nested request the new request initiated
* from the response will take care of resetting the deffered
* flag.
*/
SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
/* Validate SME/LIM/MLME state */
session_entry = pe_find_session_by_session_id(mac_ctx,
add_bss_param->sessionId);
if (session_entry == NULL) {
lim_log(mac_ctx, LOGE, FL("SessionId:%d Session Doesn't exist"),
add_bss_param->sessionId);
if (NULL != add_bss_param) {
qdf_mem_free(add_bss_param);
msg->bodyptr = NULL;
}
return;
}
bss_type = session_entry->bssType;
/* update PE session Id */
mlm_start_cnf.sessionId = session_entry->peSessionId;
if (eSIR_IBSS_MODE == bss_type) {
lim_process_ibss_mlm_add_bss_rsp(mac_ctx, msg, session_entry);
} else if (eSIR_NDI_MODE == session_entry->bssType) {
lim_process_ndi_mlm_add_bss_rsp(mac_ctx, msg, session_entry);
} else {
if (eLIM_SME_WT_START_BSS_STATE == session_entry->limSmeState) {
if (eLIM_MLM_WT_ADD_BSS_RSP_STATE !=
session_entry->limMlmState) {
/* Mesg received from HAL in Invalid state! */
lim_log(mac_ctx, LOGE,
FL("SessionId:%d Received "
" WMA_ADD_BSS_RSP in state %X"),
session_entry->peSessionId,
session_entry->limMlmState);
mlm_start_cnf.resultCode =
eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
if (0 != msg->bodyptr) {
qdf_mem_free(add_bss_param);
msg->bodyptr = NULL;
}
lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
(uint32_t *) &mlm_start_cnf);
} else
lim_process_ap_mlm_add_bss_rsp(mac_ctx, msg);
} else {
/* Called while processing assoc response */
lim_process_sta_mlm_add_bss_rsp(mac_ctx, msg,
session_entry);
}
}
#ifdef WLAN_FEATURE_11W
if (session_entry->limRmfEnabled) {
if (eSIR_SUCCESS !=
lim_send_exclude_unencrypt_ind(mac_ctx, false,
session_entry)) {
lim_log(mac_ctx, LOGE,
FL("Failed to send Exclude Unencrypted Ind."));
}
}
#endif
}
/**
* lim_process_mlm_set_sta_key_rsp() - Process STA key response
*
* @mac_ctx: Pointer to Global MAC structure
* @msg: The MsgQ header, which contains the response buffer
*
* This function is called to process the following two
* messages from HAL:
* 1) WMA_SET_BSSKEY_RSP
* 2) WMA_SET_STAKEY_RSP
* 3) WMA_SET_STA_BCASTKEY_RSP
* Upon receipt of this message from HAL,
* MLME -
* > Determines the "state" in which this message was received
* > Forwards it to the appropriate callback
* LOGIC:
* WMA_SET_BSSKEY_RSP/WMA_SET_STAKEY_RSP can be
* received by MLME while in the following state:
* MLME state = eLIM_MLM_WT_SET_BSS_KEY_STATE --OR--
* MLME state = eLIM_MLM_WT_SET_STA_KEY_STATE --OR--
* MLME state = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE
* Based on this state, this API will determine where to
* route the message to
* Assumption:
* ONLY the MLME state is being taken into account for now.
* This is because, it appears that the handling of the
* SETKEYS REQ is handled symmetrically on both the AP & STA
*
* Return: None
*/
void lim_process_mlm_set_sta_key_rsp(tpAniSirGlobal mac_ctx,
tpSirMsgQ msg)
{
uint8_t resp_reqd = 1;
tLimMlmSetKeysCnf mlm_set_key_cnf;
uint8_t session_id = 0;
tpPESession session_entry;
uint16_t key_len;
uint16_t result_status;
SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
qdf_mem_set((void *)&mlm_set_key_cnf, sizeof(tLimMlmSetKeysCnf), 0);
if (NULL == msg->bodyptr) {
PELOGE(lim_log(mac_ctx, LOGE, FL("msg bodyptr is NULL"));)
return;
}
session_id = ((tpSetStaKeyParams) msg->bodyptr)->sessionId;
session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
if (session_entry == NULL) {
PELOGE(lim_log(mac_ctx, LOGE,
FL("session does not exist for given session_id"));)
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
return;
}
if (eLIM_MLM_WT_SET_STA_KEY_STATE != session_entry->limMlmState) {
/* Mesg received from HAL in Invalid state! */
lim_log(mac_ctx, LOGE,
FL("Received unexpected [Mesg Id - %d] in state %X"),
msg->type, session_entry->limMlmState);
/* There's not much that MLME can do at this stage... */
resp_reqd = 0;
} else {
mlm_set_key_cnf.resultCode =
(uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status);
}
result_status = (uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status);
key_len = ((tpSetStaKeyParams)msg->bodyptr)->key[0].keyLength;
if (result_status == eSIR_SME_SUCCESS && key_len)
mlm_set_key_cnf.key_len_nonzero = true;
else
mlm_set_key_cnf.key_len_nonzero = false;
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
/* Restore MLME state */
session_entry->limMlmState = session_entry->limPrevMlmState;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
session_entry->peSessionId, session_entry->limMlmState));
if (resp_reqd) {
tpLimMlmSetKeysReq lpLimMlmSetKeysReq =
(tpLimMlmSetKeysReq) mac_ctx->lim.gpLimMlmSetKeysReq;
/* Prepare and Send LIM_MLM_SETKEYS_CNF */
if (NULL != lpLimMlmSetKeysReq) {
qdf_copy_macaddr(&mlm_set_key_cnf.peer_macaddr,
&lpLimMlmSetKeysReq->peer_macaddr);
/*
* Free the buffer cached for the global
* mac_ctx->lim.gpLimMlmSetKeysReq
*/
qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
}
mlm_set_key_cnf.sessionId = session_id;
lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
(uint32_t *) &mlm_set_key_cnf);
}
}
/**
* lim_process_mlm_set_bss_key_rsp() - handles BSS key
*
* @mac_ctx: A pointer to Global MAC structure
* @msg: Message from SME
*
* This function processes BSS key response and updates
* PE status accordingly.
*
* Return: NULL
*/
void lim_process_mlm_set_bss_key_rsp(tpAniSirGlobal mac_ctx,
tpSirMsgQ msg)
{
tLimMlmSetKeysCnf set_key_cnf;
uint16_t result_status;
uint8_t session_id = 0;
tpPESession session_entry;
tpLimMlmSetKeysReq set_key_req;
uint16_t key_len;
SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
qdf_mem_set((void *)&set_key_cnf, sizeof(tLimMlmSetKeysCnf), 0);
if (NULL == msg->bodyptr) {
PELOGE(lim_log(mac_ctx, LOGE, FL("msg bodyptr is null"));)
return;
}
session_id = ((tpSetBssKeyParams) msg->bodyptr)->sessionId;
session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
if (session_entry == NULL) {
PELOGE(lim_log(mac_ctx, LOGE,
FL("session does not exist for given sessionId [%d]"),
session_id);)
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
return;
}
if (eLIM_MLM_WT_SET_BSS_KEY_STATE == session_entry->limMlmState) {
result_status =
(uint16_t)(((tpSetBssKeyParams)msg->bodyptr)->status);
key_len = ((tpSetBssKeyParams)msg->bodyptr)->key[0].keyLength;
} else {
/*
* BCAST key also uses tpSetStaKeyParams.
* Done this way for readabilty.
*/
result_status =
(uint16_t)(((tpSetStaKeyParams)msg->bodyptr)->status);
key_len = ((tpSetStaKeyParams)msg->bodyptr)->key[0].keyLength;
}
if (result_status == eSIR_SME_SUCCESS && key_len)
set_key_cnf.key_len_nonzero = true;
else
set_key_cnf.key_len_nonzero = false;
/* Validate MLME state */
if (eLIM_MLM_WT_SET_BSS_KEY_STATE != session_entry->limMlmState &&
eLIM_MLM_WT_SET_STA_BCASTKEY_STATE !=
session_entry->limMlmState) {
/* Msg received from HAL in Invalid state! */
lim_log(mac_ctx, LOGE,
FL("Received unexpected [Mesg Id - %d] in state %X"),
msg->type, session_entry->limMlmState);
} else {
set_key_cnf.resultCode = result_status;
}
qdf_mem_free(msg->bodyptr);
msg->bodyptr = NULL;
/* Restore MLME state */
session_entry->limMlmState = session_entry->limPrevMlmState;
MTRACE(mac_trace
(mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
session_entry->limMlmState));
set_key_req =
(tpLimMlmSetKeysReq) mac_ctx->lim.gpLimMlmSetKeysReq;
set_key_cnf.sessionId = session_id;
/* Prepare and Send LIM_MLM_SETKEYS_CNF */
if (NULL != set_key_req) {
qdf_copy_macaddr(&set_key_cnf.peer_macaddr,
&set_key_req->peer_macaddr);
/*
* Free the buffer cached for the
* global mac_ctx->lim.gpLimMlmSetKeysReq
*/
qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
}
lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
(uint32_t *) &set_key_cnf);
}
/**
* lim_process_switch_channel_re_assoc_req()
*
***FUNCTION:
* This function is called to send the reassoc req mgmt frame after the
* switchChannelRsp message is received from HAL.
*
***LOGIC:
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure.
* @param psessionEntry - session related information.
* @param status - channel switch success/failure.
*
* @return None
*/
static void lim_process_switch_channel_re_assoc_req(tpAniSirGlobal pMac,
tpPESession psessionEntry,
QDF_STATUS status)
{
tLimMlmReassocCnf mlmReassocCnf;
tLimMlmReassocReq *pMlmReassocReq;
pMlmReassocReq =
(tLimMlmReassocReq *) (psessionEntry->pLimMlmReassocReq);
if (pMlmReassocReq == NULL) {
lim_log(pMac, LOGP,
FL
("pLimMlmReassocReq does not exist for given switchChanSession"));
mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
goto end;
}
if (status != QDF_STATUS_SUCCESS) {
PELOGE(lim_log(pMac, LOGE, FL("Change channel failed!!"));)
mlmReassocCnf.resultCode = eSIR_SME_CHANNEL_SWITCH_FAIL;
goto end;
}
/* / 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 Reassociation failure timer"));
/* Return Reassoc confirm with */
/* Resources Unavailable */
mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
goto end;
}
/* / Prepare and send Reassociation request frame */
lim_send_reassoc_req_mgmt_frame(pMac, pMlmReassocReq, psessionEntry);
return;
end:
/* Free up buffer allocated for reassocReq */
if (pMlmReassocReq != NULL) {
/* Update PE session Id */
mlmReassocCnf.sessionId = pMlmReassocReq->sessionId;
qdf_mem_free(pMlmReassocReq);
psessionEntry->pLimMlmReassocReq = NULL;
} else {
mlmReassocCnf.sessionId = 0;
}
mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
/* Update PE sessio Id */
mlmReassocCnf.sessionId = psessionEntry->peSessionId;
lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
(uint32_t *) &mlmReassocCnf);
}
/**
* lim_process_switch_channel_join_req() -Initiates probe request
*
* @mac_ctx - A pointer to Global MAC structure
* @sessionEntry - session related information.
* @status - channel switch success/failure
*
* This function is called to send the probe req mgmt frame
* after the switchChannelRsp message is received from HAL.
*
* Return None
*/
static void lim_process_switch_channel_join_req(
tpAniSirGlobal mac_ctx, tpPESession session_entry,
QDF_STATUS status)
{
tSirMacSSid ssId;
tLimMlmJoinCnf join_cnf;
if (status != QDF_STATUS_SUCCESS) {
PELOGE(lim_log(mac_ctx, LOGE, FL("Change channel failed!!"));)
goto error;
}
if ((NULL == session_entry) || (NULL == session_entry->pLimMlmJoinReq)
|| (NULL == session_entry->pLimJoinReq)) {
PELOGE(lim_log(mac_ctx, LOGE, FL("invalid pointer!!"));)
goto error;
}
session_entry->limPrevMlmState = session_entry->limMlmState;
session_entry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE;
lim_log(mac_ctx, LOG1,
FL("Sessionid %d prev lim state %d new lim state %d "
"systemrole = %d"), session_entry->peSessionId,
session_entry->limPrevMlmState,
session_entry->limMlmState, GET_LIM_SYSTEM_ROLE(session_entry));
/* Apply previously set configuration at HW */
lim_apply_configuration(mac_ctx, session_entry);
/*
* If sendDeauthBeforeCon is enabled, Send Deauth first to AP if last
* disconnection was caused by HB failure.
*/
if (mac_ctx->roam.configParam.sendDeauthBeforeCon) {
int apCount;
for (apCount = 0; apCount < 2; apCount++) {
if (!qdf_mem_cmp(session_entry->pLimMlmJoinReq->bssDescription.bssId,
mac_ctx->lim.gLimHeartBeatApMac[apCount], sizeof(tSirMacAddr))) {
lim_log(mac_ctx, LOGE, FL("Index %d Sessionid: %d Send deauth on "
"channel %d to BSSID: "MAC_ADDRESS_STR), apCount,
session_entry->peSessionId, session_entry->currentOperChannel,
MAC_ADDR_ARRAY(session_entry->pLimMlmJoinReq->bssDescription.
bssId));
lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON,
session_entry->pLimMlmJoinReq->bssDescription.bssId,
session_entry, false);
qdf_mem_zero(mac_ctx->lim.gLimHeartBeatApMac[apCount],
sizeof(tSirMacAddr));
break;
}
}
}
/* Wait for Beacon to announce join success */
qdf_mem_copy(ssId.ssId,
session_entry->ssId.ssId, session_entry->ssId.length);
ssId.length = session_entry->ssId.length;
lim_deactivate_and_change_timer(mac_ctx,
eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
/* assign appropriate sessionId to the timer object */
mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId =
session_entry->peSessionId;
lim_log(mac_ctx, LOG1,
FL("Sessionid: %d Send Probe req on channel %d ssid:%.*s "
"BSSID: " MAC_ADDRESS_STR), session_entry->peSessionId,
session_entry->currentOperChannel, ssId.length, ssId.ssId,
MAC_ADDR_ARRAY(
session_entry->pLimMlmJoinReq->bssDescription.bssId));
/*
* We need to wait for probe response, so start join
* timeout timer.This timer will be deactivated once
* we receive probe response.
*/
MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
session_entry->peSessionId, eLIM_JOIN_FAIL_TIMER));
if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimJoinFailureTimer) !=
TX_SUCCESS) {
lim_log(mac_ctx, LOGP,
FL("couldn't activate Join failure timer"));
session_entry->limMlmState = session_entry->limPrevMlmState;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
session_entry->peSessionId,
mac_ctx->lim.gLimMlmState));
goto error;
}
/* include additional IE if there is */
lim_send_probe_req_mgmt_frame(mac_ctx, &ssId,
session_entry->pLimMlmJoinReq->bssDescription.bssId,
session_entry->currentOperChannel, session_entry->selfMacAddr,
session_entry->dot11mode,
session_entry->pLimJoinReq->addIEScan.length,
session_entry->pLimJoinReq->addIEScan.addIEdata);
if (session_entry->pePersona == QDF_P2P_CLIENT_MODE) {
/* Activate Join Periodic Probe Req timer */
if (tx_timer_activate
(&mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer)
!= TX_SUCCESS) {
lim_log(mac_ctx, LOGP,
FL("Periodic JoinReq timer activate failed"));
goto error;
}
}
return;
error:
if (NULL != session_entry) {
if (session_entry->pLimMlmJoinReq) {
qdf_mem_free(session_entry->pLimMlmJoinReq);
session_entry->pLimMlmJoinReq = NULL;
}
if (session_entry->pLimJoinReq) {
qdf_mem_free(session_entry->pLimJoinReq);
session_entry->pLimJoinReq = NULL;
}
join_cnf.sessionId = session_entry->peSessionId;
} else {
join_cnf.sessionId = 0;
}
join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, (uint32_t *)&join_cnf);
}
/**
* lim_process_switch_channel_rsp()
*
***FUNCTION:
* This function is called to process switchChannelRsp message from HAL.
*
***LOGIC:
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure
* @param body - message body.
*
* @return None
*/
void lim_process_switch_channel_rsp(tpAniSirGlobal pMac, void *body)
{
tpSwitchChannelParams pChnlParams = NULL;
QDF_STATUS status;
uint16_t channelChangeReasonCode;
uint8_t peSessionId;
tpPESession psessionEntry;
/* we need to process the deferred message since the initiating req. there might be nested request. */
/* in the case of nested request the new request initiated from the response will take care of resetting */
/* the deffered flag. */
SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
pChnlParams = (tpSwitchChannelParams) body;
status = pChnlParams->status;
peSessionId = pChnlParams->peSessionId;
psessionEntry = pe_find_session_by_session_id(pMac, peSessionId);
if (psessionEntry == NULL) {
lim_log(pMac, LOGP,
FL("session does not exist for given sessionId"));
return;
}
/* HAL fills in the tx power used for mgmt frames in this field. */
/* Store this value to use in TPC report IE. */
rrm_cache_mgmt_tx_power(pMac, pChnlParams->txMgmtPower, psessionEntry);
channelChangeReasonCode = psessionEntry->channelChangeReasonCode;
/* initialize it back to invalid id */
psessionEntry->chainMask = pChnlParams->chainMask;
psessionEntry->smpsMode = pChnlParams->smpsMode;
psessionEntry->channelChangeReasonCode = 0xBAD;
lim_log(pMac, LOG1, FL("channelChangeReasonCode %d"),
channelChangeReasonCode);
switch (channelChangeReasonCode) {
case LIM_SWITCH_CHANNEL_REASSOC:
lim_process_switch_channel_re_assoc_req(pMac, psessionEntry, status);
break;
case LIM_SWITCH_CHANNEL_JOIN:
lim_process_switch_channel_join_req(pMac, psessionEntry, status);
break;
case LIM_SWITCH_CHANNEL_OPERATION:
/*
* The above code should also use the callback.
* mechanism below, there is scope for cleanup here.
* THat way all this response handler does is call the call back
* We can get rid of the reason code here.
*/
if (pMac->lim.gpchangeChannelCallback) {
PELOG1(lim_log
(pMac, LOG1,
"Channel changed hence invoke registered call back");
)
pMac->lim.gpchangeChannelCallback(pMac, status,
pMac->lim.
gpchangeChannelData,
psessionEntry);
}
/* If MCC upgrade/DBS downgrade happended during channel switch,
* the policy manager connection table needs to be updated.
*/
cds_update_connection_info(psessionEntry->smeSessionId);
if (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) {
lim_log(pMac, LOG1,
FL("Send p2p operating channel change conf action frame once first beacon is received on new channel"));
psessionEntry->send_p2p_conf_frame = true;
}
break;
case LIM_SWITCH_CHANNEL_SAP_DFS:
{
/* Note: This event code specific to SAP mode
* When SAP session issues channel change as performing
* DFS, we will come here. Other sessions, for e.g. P2P
* will have to define their own event code and channel
* switch handler. This is required since the SME may
* require completely different information for P2P unlike
* SAP.
*/
lim_send_sme_ap_channel_switch_resp(pMac, psessionEntry,
pChnlParams);
/* If MCC upgrade/DBS downgrade happended during channel switch,
* the policy manager connection table needs to be updated.
*/
cds_update_connection_info(psessionEntry->smeSessionId);
cds_set_do_hw_mode_change_flag(true);
}
break;
default:
break;
}
qdf_mem_free(body);
}
void lim_send_beacon_ind(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
tBeaconGenParams *pBeaconGenParams = NULL;
tSirMsgQ limMsg;
/** Allocate the Memory for Beacon Pre Message and for Stations in PoweSave*/
if (psessionEntry == NULL) {
PELOGE(lim_log(pMac, LOGE,
FL("Error:Unable to get the PESessionEntry"));
)
return;
}
pBeaconGenParams = qdf_mem_malloc(sizeof(*pBeaconGenParams));
if (NULL == pBeaconGenParams) {
PELOGE(lim_log(pMac, LOGP,
FL
("Unable to allocate memory during sending beaconPreMessage"));
)
return;
}
qdf_mem_copy((void *)pBeaconGenParams->bssId,
(void *)psessionEntry->bssId, QDF_MAC_ADDR_SIZE);
limMsg.bodyptr = pBeaconGenParams;
sch_process_pre_beacon_ind(pMac, &limMsg);
return;
}
#ifdef FEATURE_WLAN_SCAN_PNO
/**
* lim_send_sme_scan_cache_updated_ind()
*
***FUNCTION:
* This function is used to post WMA_SME_SCAN_CACHE_UPDATED message to WMA.
* This message is the indication to WMA that all scan cache results
* are updated from LIM to SME. Mainly used only in PNO offload case.
*
***LOGIC:
*
***ASSUMPTIONS:
* This function should be called after posting scan cache results to SME.
*
***NOTE:
* NA
*
* @return None
*/
static void lim_send_sme_scan_cache_updated_ind(uint8_t sessionId)
{
cds_msg_t msg;
msg.type = WMA_SME_SCAN_CACHE_UPDATED;
msg.reserved = 0;
msg.bodyptr = NULL;
msg.bodyval = sessionId;
if (!QDF_IS_STATUS_SUCCESS
(cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)))
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
"%s: Not able to post WMA_SME_SCAN_CACHE_UPDATED message to WMA",
__func__);
}
#endif
static void lim_send_scan_offload_complete(tpAniSirGlobal pMac,
tSirScanOffloadEvent *pScanEvent)
{
pMac->lim.gLimRspReqd = false;
lim_send_sme_scan_rsp(pMac, pScanEvent->reasonCode,
pScanEvent->sessionId, 0, pScanEvent->scanId);
#ifdef FEATURE_WLAN_SCAN_PNO
lim_send_sme_scan_cache_updated_ind(pScanEvent->sessionId);
#endif
}
void lim_process_rx_scan_event(tpAniSirGlobal pMac, void *buf)
{
tSirScanOffloadEvent *pScanEvent = (tSirScanOffloadEvent *) buf;
switch (pScanEvent->event) {
case SIR_SCAN_EVENT_STARTED:
break;
case SIR_SCAN_EVENT_START_FAILED:
case SIR_SCAN_EVENT_COMPLETED:
if (ROC_SCAN_REQUESTOR_ID == pScanEvent->requestor) {
lim_send_sme_roc_rsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP,
QDF_STATUS_SUCCESS,
pScanEvent->sessionId,
pScanEvent->scanId);
qdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
pMac->lim.gpLimRemainOnChanReq = NULL;
/*
* If remain on channel timer expired and action frame
* is pending then indicate confirmation with status
* failure.
*/
if (pMac->lim.mgmtFrameSessionId != 0xff) {
lim_p2p_action_cnf(pMac, NULL, false, NULL);
pMac->lim.mgmtFrameSessionId = 0xff;
}
} else if (PREAUTH_REQUESTOR_ID == pScanEvent->requestor) {
lim_preauth_scan_event_handler(pMac, pScanEvent->event,
pScanEvent->sessionId,
pScanEvent->scanId);
} else {
lim_send_scan_offload_complete(pMac, pScanEvent);
}
break;
case SIR_SCAN_EVENT_FOREIGN_CHANNEL:
if (ROC_SCAN_REQUESTOR_ID == pScanEvent->requestor) {
/*Send Ready on channel indication to SME */
if (pMac->lim.gpLimRemainOnChanReq) {
lim_send_sme_roc_rsp(pMac,
eWNI_SME_REMAIN_ON_CHN_RDY_IND,
QDF_STATUS_SUCCESS,
pScanEvent->sessionId,
pScanEvent->scanId);
} else {
lim_log(pMac, LOGE,
FL("gpLimRemainOnChanReq is NULL"));
}
} else if (PREAUTH_REQUESTOR_ID == pScanEvent->requestor) {
lim_preauth_scan_event_handler(pMac, pScanEvent->event,
pScanEvent->sessionId,
pScanEvent->scanId);
}
break;
case SIR_SCAN_EVENT_BSS_CHANNEL:
case SIR_SCAN_EVENT_DEQUEUED:
case SIR_SCAN_EVENT_PREEMPTED:
default:
QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
"Received unhandled scan event %u",
pScanEvent->event);
}
qdf_mem_free(buf);
}