blob: f68f7b08bbf63a9ae4564979b323cfb7598fb83f [file] [log] [blame]
/*
* Copyright (c) 2011-2015 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.
*/
/*
* This file lim_timer_utils.cc contains the utility functions
* LIM uses for handling various timers.
* Author: Chandra Modumudi
* Date: 02/13/02
* History:-
* Date Modified by Modification Information
* --------------------------------------------------------------------
*/
#include "lim_types.h"
#include "lim_utils.h"
#include "lim_assoc_utils.h"
#include "lim_security_utils.h"
/* channel Switch Timer in ticks */
#define LIM_CHANNEL_SWITCH_TIMER_TICKS 1
/* Lim Quite timer in ticks */
#define LIM_QUIET_TIMER_TICKS 100
/* Lim Quite BSS timer interval in ticks */
#define LIM_QUIET_BSS_TIMER_TICK 100
/* Lim KeepAlive timer default (3000)ms */
#define LIM_KEEPALIVE_TIMER_MS 3000
/* Lim JoinProbeRequest Retry timer default (200)ms */
#define LIM_JOIN_PROBE_REQ_TIMER_MS 200
/* This timer is a periodic timer which expires at every 1 sec to
convert ACTIVE DFS channel to DFS channels */
#define ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT 1000
static bool
lim_create_non_ap_timers(tpAniSirGlobal pMac)
{
uint32_t cfgValue;
/* Create Channel Switch Timer */
if (tx_timer_create(&pMac->lim.limTimers.gLimChannelSwitchTimer,
"CHANNEL SWITCH TIMER",
lim_channel_switch_timer_handler, 0,
LIM_CHANNEL_SWITCH_TIMER_TICKS,
0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("failed to create Ch Switch timer"));
return false;
}
/* Create Quiet Timer
* This is used on the STA to go and shut-off Tx/Rx "after" the
* specified quiteInterval
*/
if (tx_timer_create(&pMac->lim.limTimers.gLimQuietTimer,
"QUIET TIMER", lim_quiet_timer_handler,
SIR_LIM_QUIET_TIMEOUT, LIM_QUIET_TIMER_TICKS,
0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("failed to create Quiet Begin Timer"));
return false;
}
/* Create Quiet BSS Timer
* After the specified quiteInterval, determined by gLimQuietTimer, this
* timer, gLimQuietBssTimer, trigger and put the STA to sleep for the
* specified gLimQuietDuration
*/
if (tx_timer_create(&pMac->lim.limTimers.gLimQuietBssTimer,
"QUIET BSS TIMER", lim_quiet_bss_timer_handler,
SIR_LIM_QUIET_BSS_TIMEOUT, LIM_QUIET_BSS_TIMER_TICK,
0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("failed to create Quiet Bss Timer"));
return false;
}
if (wlan_cfg_get_int(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
&cfgValue) != eSIR_SUCCESS)
lim_log(pMac, LOGP,
FL("could not retrieve JoinFailureTimeout value"));
cfgValue = SYS_MS_TO_TICKS(cfgValue);
/* Create Join failure timer and activate it later */
if (tx_timer_create(&pMac->lim.limTimers.gLimJoinFailureTimer,
"JOIN FAILURE TIMEOUT",
lim_timer_handler, SIR_LIM_JOIN_FAIL_TIMEOUT,
cfgValue, 0,
TX_NO_ACTIVATE) != TX_SUCCESS) {
/* / Could not create Join failure timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("could not create Join failure timer"));
return false;
}
/* Send unicast probe req frame every 200 ms */
if (tx_timer_create(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer,
"Periodic Join Probe Request Timer",
lim_timer_handler,
SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT,
SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS), 0,
TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP,
FL("could not create Periodic Join Probe Request tmr"));
return false;
}
if (wlan_cfg_get_int(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
&cfgValue) != eSIR_SUCCESS)
lim_log(pMac, LOGP,
FL("could not retrieve AssocFailureTimeout value"));
cfgValue = SYS_MS_TO_TICKS(cfgValue);
/* Create Association failure timer and activate it later */
if (tx_timer_create(&pMac->lim.limTimers.gLimAssocFailureTimer,
"ASSOC FAILURE TIMEOUT",
lim_assoc_failure_timer_handler, LIM_ASSOC,
cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP,
FL("could not create Association failure timer"));
return false;
}
if (wlan_cfg_get_int(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
&cfgValue) != eSIR_SUCCESS)
lim_log(pMac, LOGP,
FL("could not retrieve ReassocFailureTimeout value"));
cfgValue = SYS_MS_TO_TICKS(cfgValue);
/* Create Association failure timer and activate it later */
if (tx_timer_create
(&pMac->lim.limTimers.gLimReassocFailureTimer,
"REASSOC FAILURE TIMEOUT", lim_assoc_failure_timer_handler,
LIM_REASSOC, cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP,
FL("could not create Reassociation failure timer"));
return false;
}
if (wlan_cfg_get_int(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &cfgValue)
!= eSIR_SUCCESS)
lim_log(pMac, LOGP,
FL("Fail to get WNI_CFG_ADDTS_RSP_TIMEOUT "));
cfgValue = SYS_MS_TO_TICKS(cfgValue);
/* Create Addts response timer and activate it later */
if (tx_timer_create(&pMac->lim.limTimers.gLimAddtsRspTimer,
"ADDTS RSP TIMEOUT",
lim_addts_response_timer_handler,
SIR_LIM_ADDTS_RSP_TIMEOUT,
cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP,
FL("could not create Addts response timer"));
return false;
}
if (wlan_cfg_get_int(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
&cfgValue) != eSIR_SUCCESS)
lim_log(pMac, LOGP,
FL("could not retrieve AuthFailureTimeout value"));
cfgValue = SYS_MS_TO_TICKS(cfgValue);
/* Create Auth failure timer and activate it later */
if (tx_timer_create(&pMac->lim.limTimers.gLimAuthFailureTimer,
"AUTH FAILURE TIMEOUT",
lim_timer_handler,
SIR_LIM_AUTH_FAIL_TIMEOUT,
cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("could not create Auth failure timer"));
return false;
}
if (wlan_cfg_get_int(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT,
&cfgValue) != eSIR_SUCCESS)
lim_log(pMac, LOGP,
FL("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value"));
/* Change timer to reactivate it in future */
cfgValue = SYS_MS_TO_TICKS(cfgValue);
if (tx_timer_create(&pMac->lim.limTimers.gLimProbeAfterHBTimer,
"Probe after Heartbeat TIMEOUT",
lim_timer_handler,
SIR_LIM_PROBE_HB_FAILURE_TIMEOUT,
cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("unable to create ProbeAfterHBTimer"));
return false;
}
return true;
}
/**
* lim_create_timers()
*
* @pMac : Pointer to Global MAC structure
*
* This function is called upon receiving
* 1. SME_START_REQ for STA in ESS role
* 2. SME_START_BSS_REQ for AP role & STA in IBSS role
*
* @return : status of operation
*/
uint32_t lim_create_timers(tpAniSirGlobal pMac)
{
uint32_t cfgValue, i = 0;
uint32_t cfgValue1;
PELOG1(lim_log(pMac, LOG1,
FL("Creating Timers used by LIM module in Role %d"),
pMac->lim.gLimSystemRole);)
if (wlan_cfg_get_int(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
&cfgValue) != eSIR_SUCCESS) {
lim_log(pMac, LOGP,
FL("could not retrieve MinChannelTimeout value"));
}
cfgValue = SYS_MS_TO_TICKS(cfgValue);
/* Periodic probe request timer value is half of the Min channel
* timer. Probe request sends periodically till min/max channel
* timer expires
*/
cfgValue1 = cfgValue / 2;
/* Create periodic probe request timer and activate them later */
if (cfgValue1 >= 1
&& (tx_timer_create(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer,
"Periodic Probe Request Timer", lim_timer_handler,
SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT, cfgValue1, 0,
TX_NO_ACTIVATE) != TX_SUCCESS)) {
lim_log(pMac, LOGP,
FL("could not create periodic probe timer"));
goto err_timer;
}
if (wlan_cfg_get_int(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
&cfgValue) != eSIR_SUCCESS)
lim_log(pMac, LOGP,
FL("could not retrieve MAXChannelTimeout value"));
cfgValue = SYS_MS_TO_TICKS(cfgValue);
/* Limiting max numm of probe req for each channel scan */
pMac->lim.maxProbe = (cfgValue / cfgValue1);
if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE)
if (false == lim_create_non_ap_timers(pMac))
goto err_timer;
cfgValue = SYS_MS_TO_TICKS(LIM_HASH_MISS_TIMER_MS);
if (tx_timer_create(
&pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer,
"Disassoc throttle TIMEOUT",
lim_send_disassoc_frame_threshold_handler,
SIR_LIM_HASH_MISS_THRES_TIMEOUT, cfgValue, cfgValue,
TX_AUTO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP,
FL("create Disassociate throttle timer failed"));
goto err_timer;
}
PELOG1(lim_log(pMac, LOG1, FL("Created Disassociate throttle timer "));)
/* Create all CNF_WAIT Timers upfront */
if (wlan_cfg_get_int(pMac, WNI_CFG_WT_CNF_TIMEOUT, &cfgValue)
!= eSIR_SUCCESS) {
lim_log(pMac, LOGP, FL("could not retrieve CNF timeout value"));
}
cfgValue = SYS_MS_TO_TICKS(cfgValue);
for (i = 0; i < (pMac->lim.maxStation + 1); i++) {
if (tx_timer_create(&pMac->lim.limTimers.gpLimCnfWaitTimer[i],
"CNF_MISS_TIMEOUT",
lim_cnf_wait_tmer_handler,
(uint32_t) i, cfgValue,
0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("Cannot create CNF wait timer"));
goto err_timer;
}
}
/* Alloc and init table for the preAuth timer list */
if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_NUM_PRE_AUTH,
&cfgValue) != eSIR_SUCCESS)
lim_log(pMac, LOGP, FL("could not retrieve mac preauth value"));
pMac->lim.gLimPreAuthTimerTable.numEntry = cfgValue;
pMac->lim.gLimPreAuthTimerTable.pTable =
cdf_mem_malloc(cfgValue * sizeof(tLimPreAuthNode));
if (pMac->lim.gLimPreAuthTimerTable.pTable == NULL) {
lim_log(pMac, LOGP, FL("AllocateMemory failed!"));
goto err_timer;
}
lim_init_pre_auth_timer_table(pMac, &pMac->lim.gLimPreAuthTimerTable);
PELOG1(lim_log(pMac, LOG1,
FL("alloc and init table for preAuth timers"));)
if (wlan_cfg_get_int(pMac, WNI_CFG_OLBC_DETECT_TIMEOUT,
&cfgValue) != eSIR_SUCCESS)
lim_log(pMac, LOGP,
FL("could not retrieve OLBD detect timeout value"));
cfgValue = SYS_MS_TO_TICKS(cfgValue);
if (tx_timer_create(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer,
"OLBC UPDATE CACHE TIMEOUT",
lim_update_olbc_cache_timer_handler,
SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT, cfgValue,
cfgValue, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("Cannot create update OLBC cache tmr"));
goto err_timer;
}
#ifdef WLAN_FEATURE_VOWIFI_11R
/* In future we need to use the auth timer, cause the pre auth session
* will be introduced before sending Auth frame. We need to go off
* channel and come back to home channel
*/
cfgValue = 1000;
cfgValue = SYS_MS_TO_TICKS(cfgValue);
if (tx_timer_create(&pMac->lim.limTimers.gLimFTPreAuthRspTimer,
"FT PREAUTH RSP TIMEOUT",
lim_timer_handler, SIR_LIM_FT_PREAUTH_RSP_TIMEOUT,
cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("could not create Join failure timer"));
goto err_timer;
}
#endif
cfgValue = 1000;
cfgValue = SYS_MS_TO_TICKS(cfgValue);
if (tx_timer_create(&pMac->lim.limTimers.gLimRemainOnChannelTimer,
"FT PREAUTH RSP TIMEOUT",
lim_timer_handler, SIR_LIM_REMAIN_CHN_TIMEOUT,
cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("could not create Join failure timer"));
goto err_timer;
}
cfgValue = 1000;
cfgValue = SYS_MS_TO_TICKS(cfgValue);
if (tx_timer_create(&pMac->lim.limTimers.gLimDisassocAckTimer,
"DISASSOC ACK TIMEOUT",
lim_timer_handler, SIR_LIM_DISASSOC_ACK_TIMEOUT,
cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP, FL("could not DISASSOC ACK TIMEOUT timer"));
goto err_timer;
}
cfgValue = 1000;
cfgValue = SYS_MS_TO_TICKS(cfgValue);
if (tx_timer_create(&pMac->lim.limTimers.gLimDeauthAckTimer,
"DISASSOC ACK TIMEOUT",
lim_timer_handler, SIR_LIM_DEAUTH_ACK_TIMEOUT,
cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP,
FL("could not create DEAUTH ACK TIMEOUT timer"));
goto err_timer;
}
/* (> no of BI* no of TUs per BI * 1TU in msec +
* p2p start time offset*1 TU in msec = 2*100*1.024 + 5*1.024
* = 204.8 + 5.12 = 209.20)
*/
cfgValue = LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE;
cfgValue = SYS_MS_TO_TICKS(cfgValue);
if (tx_timer_create(
&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer,
"Single Shot NOA Insert timeout", lim_timer_handler,
SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT, cfgValue, 0,
TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGP,
FL("Can't create Single Shot NOA Insert Timeout tmr"));
goto err_timer;
}
cfgValue = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT;
cfgValue = SYS_MS_TO_TICKS(cfgValue);
if (tx_timer_create(
&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer,
"ACTIVE TO PASSIVE CHANNEL", lim_timer_handler,
SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE, cfgValue, 0,
TX_NO_ACTIVATE) != TX_SUCCESS) {
lim_log(pMac, LOGW,
FL("could not create timer for passive channel to active channel"));
goto err_timer;
}
return TX_SUCCESS;
err_timer:
tx_timer_delete(&pMac->lim.limTimers.gLimDeauthAckTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimDisassocAckTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimRemainOnChannelTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
while (((int32_t)-- i) >= 0) {
tx_timer_delete(&pMac->lim.limTimers.gpLimCnfWaitTimer[i]);
}
tx_timer_delete(&pMac->lim.limTimers.
gLimSendDisassocFrameThresholdTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimAuthFailureTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimAddtsRspTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimReassocFailureTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimAssocFailureTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimJoinFailureTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimQuietBssTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimQuietTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimChannelSwitchTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer);
tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer);
if (NULL != pMac->lim.gLimPreAuthTimerTable.pTable) {
cdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable);
pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
}
return TX_TIMER_ERROR;
} /****** end lim_create_timers() ******/
/**
* lim_timer_handler()
*
***FUNCTION:
* This function is called upon
* 1. MIN_CHANNEL, MAX_CHANNEL timer expiration during scanning
* 2. JOIN_FAILURE timer expiration while joining a BSS
* 3. AUTH_FAILURE timer expiration while authenticating with a peer
* 4. Heartbeat timer expiration on STA
* 5. Background scan timer expiration on STA
* 6. AID release, Pre-auth cleanup and Link monitoring timer
* expiration on AP
*
***LOGIC:
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param param - Message corresponding to the timer that expired
*
* @return None
*/
void lim_timer_handler(void *pMacGlobal, uint32_t param)
{
uint32_t statusCode;
tSirMsgQ msg;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
/* Prepare and post message to LIM Message Queue */
msg.type = (uint16_t) param;
msg.bodyptr = NULL;
msg.bodyval = 0;
if ((statusCode = lim_post_msg_api(pMac, &msg)) != eSIR_SUCCESS)
lim_log(pMac, LOGE,
FL("posting message %X to LIM failed, reason=%d"),
msg.type, statusCode);
} /****** end lim_timer_handler() ******/
/**
* lim_addts_response_timer_handler()
*
***FUNCTION:
* This function is called upon Addts response timer expiration on sta
*
***LOGIC:
* Message SIR_LIM_ADDTS_RSP_TIMEOUT is posted to gSirLimMsgQ
* when this function is executed.
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param param - pointer to pre-auth node
*
* @return None
*/
void lim_addts_response_timer_handler(void *pMacGlobal, uint32_t param)
{
tSirMsgQ msg;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
/* Prepare and post message to LIM Message Queue */
msg.type = SIR_LIM_ADDTS_RSP_TIMEOUT;
msg.bodyval = param;
msg.bodyptr = NULL;
lim_post_msg_api(pMac, &msg);
} /****** end lim_auth_response_timer_handler() ******/
/**
* lim_auth_response_timer_handler()
*
***FUNCTION:
* This function is called upon Auth response timer expiration on AP
*
***LOGIC:
* Message SIR_LIM_AUTH_RSP_TIMEOUT is posted to gSirLimMsgQ
* when this function is executed.
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param param - pointer to pre-auth node
*
* @return None
*/
void lim_auth_response_timer_handler(void *pMacGlobal, uint32_t param)
{
tSirMsgQ msg;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
/* Prepare and post message to LIM Message Queue */
msg.type = SIR_LIM_AUTH_RSP_TIMEOUT;
msg.bodyptr = NULL;
msg.bodyval = (uint32_t) param;
lim_post_msg_api(pMac, &msg);
} /****** end lim_auth_response_timer_handler() ******/
/**
* lim_assoc_failure_timer_handler()
*
* @mac_global : Pointer to Global MAC structure
* @param : Indicates whether this is assoc or reassoc failure timeout
*
* This function is called upon Re/Assoc failure timer expiration on STA.
* Message SIR_LIM_ASSOC_FAIL_TIMEOUT is posted to gSirLimMsgQ when this
* function is executed.
*
* Return void
*/
void lim_assoc_failure_timer_handler(void *mac_global, uint32_t param)
{
tSirMsgQ msg;
tpAniSirGlobal mac_ctx = (tpAniSirGlobal) mac_global;
tpPESession session = NULL;
#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
session = mac_ctx->lim.pSessionEntry;
if (LIM_REASSOC == param && NULL != session
&& session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE) {
lim_log(mac_ctx, LOGE, FL("Reassoc timeout happened"));
if (mac_ctx->lim.reAssocRetryAttempt <
LIM_MAX_REASSOC_RETRY_LIMIT) {
lim_send_retry_reassoc_req_frame(mac_ctx,
session->pLimMlmReassocRetryReq, session);
mac_ctx->lim.reAssocRetryAttempt++;
lim_log(mac_ctx, LOGW,
FL("Reassoc request retry is sent %d times"),
mac_ctx->lim.reAssocRetryAttempt);
return;
} else {
lim_log(mac_ctx, LOGW,
FL("Reassoc request retry MAX(%d) reached"),
LIM_MAX_REASSOC_RETRY_LIMIT);
if (NULL != session->pLimMlmReassocRetryReq) {
cdf_mem_free(session->pLimMlmReassocRetryReq);
session->pLimMlmReassocRetryReq = NULL;
}
}
}
#endif
/* Prepare and post message to LIM Message Queue */
msg.type = SIR_LIM_ASSOC_FAIL_TIMEOUT;
msg.bodyval = (uint32_t) param;
msg.bodyptr = NULL;
lim_post_msg_api(mac_ctx, &msg);
} /****** end lim_assoc_failure_timer_handler() ******/
/**
* lim_update_olbc_cache_timer_handler()
*
***FUNCTION:
* This function is called upon update olbc cache timer expiration
* on STA
*
***LOGIC:
* Message SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT is posted to gSirLimMsgQ
* when this function is executed.
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param
*
* @return None
*/
void lim_update_olbc_cache_timer_handler(void *pMacGlobal, uint32_t param)
{
tSirMsgQ msg;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
/* Prepare and post message to LIM Message Queue */
msg.type = SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT;
msg.bodyval = 0;
msg.bodyptr = NULL;
lim_post_msg_api(pMac, &msg);
} /****** end lim_update_olbc_cache_timer_handler() ******/
/**
* lim_deactivate_and_change_timer()
*
***FUNCTION:
* This function is called to deactivate and change a timer
* for future re-activation
*
***LOGIC:
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure
* @param timerId - enum of timer to be deactivated and changed
* This enum is defined in lim_utils.h file
*
* @return None
*/
void lim_deactivate_and_change_timer(tpAniSirGlobal pMac, uint32_t timerId)
{
uint32_t val = 0;
MTRACE(mac_trace
(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, timerId));
switch (timerId) {
case eLIM_ADDTS_RSP_TIMER:
pMac->lim.gLimAddtsRspTimerCount++;
if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer)
!= TX_SUCCESS) {
/* Could not deactivate AddtsRsp Timer */
/* Log error */
lim_log(pMac, LOGP,
FL("Unable to deactivate AddtsRsp timer"));
}
break;
case eLIM_PERIODIC_PROBE_REQ_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer)
!= TX_SUCCESS) {
/* Could not deactivate min channel timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("Unable to deactivate periodic timer"));
}
val =
SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTime) /
2;
if (tx_timer_change
(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer, val,
0) != TX_SUCCESS) {
/* Could not change min channel timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("Unable to change periodic timer"));
}
break;
case eLIM_JOIN_FAIL_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimJoinFailureTimer)
!= TX_SUCCESS) {
/**
* Could not deactivate Join Failure
* timer. Log error.
*/
lim_log(pMac, LOGP,
FL("Unable to deactivate Join Failure timer"));
}
if (wlan_cfg_get_int(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
&val) != eSIR_SUCCESS) {
/**
* Could not get JoinFailureTimeout value
* from CFG. Log error.
*/
lim_log(pMac, LOGP,
FL
("could not retrieve JoinFailureTimeout value"));
}
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change(&pMac->lim.limTimers.gLimJoinFailureTimer,
val, 0) != TX_SUCCESS) {
/**
* Could not change Join Failure
* timer. Log error.
*/
lim_log(pMac, LOGP,
FL("Unable to change Join Failure timer"));
}
break;
case eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer)
!= TX_SUCCESS) {
/* Could not deactivate periodic join req Times. */
lim_log(pMac, LOGP,
FL
("Unable to deactivate periodic join request timer"));
}
val = SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS);
if (tx_timer_change
(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, val,
0) != TX_SUCCESS) {
/* Could not change periodic join req times. */
/* Log error */
lim_log(pMac, LOGP,
FL
("Unable to change periodic join request timer"));
}
break;
case eLIM_AUTH_FAIL_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimAuthFailureTimer)
!= TX_SUCCESS) {
/* Could not deactivate Auth failure timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("Unable to deactivate auth failure timer"));
}
/* Change timer to reactivate it in future */
if (wlan_cfg_get_int(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
&val) != eSIR_SUCCESS) {
/**
* Could not get AuthFailureTimeout value
* from CFG. Log error.
*/
lim_log(pMac, LOGP,
FL
("could not retrieve AuthFailureTimeout value"));
}
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change(&pMac->lim.limTimers.gLimAuthFailureTimer,
val, 0) != TX_SUCCESS) {
/* Could not change Authentication failure timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("unable to change Auth failure timer"));
}
break;
case eLIM_ASSOC_FAIL_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimAssocFailureTimer) !=
TX_SUCCESS) {
/* Could not deactivate Association failure timer. */
/* Log error */
lim_log(pMac, LOGP,
FL
("unable to deactivate Association failure timer"));
}
/* Change timer to reactivate it in future */
if (wlan_cfg_get_int(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
&val) != eSIR_SUCCESS) {
/**
* Could not get AssocFailureTimeout value
* from CFG. Log error.
*/
lim_log(pMac, LOGP,
FL
("could not retrieve AssocFailureTimeout value"));
}
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change(&pMac->lim.limTimers.gLimAssocFailureTimer,
val, 0) != TX_SUCCESS) {
/* Could not change Association failure timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("unable to change Assoc failure timer"));
}
break;
case eLIM_REASSOC_FAIL_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimReassocFailureTimer) !=
TX_SUCCESS) {
/* Could not deactivate Reassociation failure timer. */
/* Log error */
lim_log(pMac, LOGP,
FL
("unable to deactivate Reassoc failure timer"));
}
/* Change timer to reactivate it in future */
if (wlan_cfg_get_int(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
&val) != eSIR_SUCCESS) {
/**
* Could not get ReassocFailureTimeout value
* from CFG. Log error.
*/
lim_log(pMac, LOGP,
FL
("could not retrieve ReassocFailureTimeout value"));
}
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change
(&pMac->lim.limTimers.gLimReassocFailureTimer, val,
0) != TX_SUCCESS) {
/* Could not change Reassociation failure timer. */
/* Log error */
lim_log(pMac, LOGP,
FL
("unable to change Reassociation failure timer"));
}
break;
case eLIM_PROBE_AFTER_HB_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimProbeAfterHBTimer) !=
TX_SUCCESS) {
/* Could not deactivate Heartbeat timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("unable to deactivate probeAfterHBTimer"));
} else {
lim_log(pMac, LOG1,
FL("Deactivated probe after hb timer"));
}
if (wlan_cfg_get_int(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT,
&val) != eSIR_SUCCESS) {
/**
* Could not get PROBE_AFTER_HB_FAILURE
* value from CFG. Log error.
*/
lim_log(pMac, LOGP,
FL
("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value"));
}
/* Change timer to reactivate it in future */
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change(&pMac->lim.limTimers.gLimProbeAfterHBTimer,
val, 0) != TX_SUCCESS) {
/* Could not change HeartBeat timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("unable to change ProbeAfterHBTimer"));
} else {
lim_log(pMac, LOGW,
FL("Probe after HB timer value is changed = %u"),
val);
}
break;
case eLIM_LEARN_DURATION_TIMER:
break;
#ifdef WLAN_FEATURE_VOWIFI_11R
case eLIM_FT_PREAUTH_RSP_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimFTPreAuthRspTimer) !=
TX_SUCCESS) {
/**
** Could not deactivate Join Failure
** timer. Log error.
**/
lim_log(pMac, LOGP,
FL
("Unable to deactivate Preauth response Failure timer"));
return;
}
val = 1000;
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change(&pMac->lim.limTimers.gLimFTPreAuthRspTimer,
val, 0) != TX_SUCCESS) {
/**
* Could not change Join Failure
* timer. Log error.
*/
lim_log(pMac, LOGP,
FL("Unable to change Join Failure timer"));
return;
}
break;
#endif
case eLIM_REMAIN_CHN_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimRemainOnChannelTimer) !=
TX_SUCCESS) {
/**
** Could not deactivate Join Failure
** timer. Log error.
**/
lim_log(pMac, LOGP,
FL("Unable to deactivate Remain on Chn timer"));
return;
}
val = 1000;
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change
(&pMac->lim.limTimers.gLimRemainOnChannelTimer, val,
0) != TX_SUCCESS) {
/**
* Could not change Join Failure
* timer. Log error.
*/
lim_log(pMac, LOGP, FL("Unable to change timer"));
return;
}
break;
case eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer) !=
TX_SUCCESS) {
/**
** Could not deactivate Active to passive channel timer.
** Log error.
**/
lim_log(pMac, LOGP, FL("Unable to Deactivate "
"Active to passive channel timer"));
return;
}
val = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT;
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change
(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer, val,
0) != TX_SUCCESS) {
/**
* Could not change timer to check scan type for passive channel.
* timer. Log error.
*/
lim_log(pMac, LOGP, FL("Unable to change timer"));
return;
}
break;
case eLIM_DISASSOC_ACK_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimDisassocAckTimer) != TX_SUCCESS) {
/**
** Could not deactivate Join Failure
** timer. Log error.
**/
lim_log(pMac, LOGP,
FL("Unable to deactivate Disassoc ack timer"));
return;
}
val = 1000;
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change(&pMac->lim.limTimers.gLimDisassocAckTimer,
val, 0) != TX_SUCCESS) {
/**
* Could not change Join Failure
* timer. Log error.
*/
lim_log(pMac, LOGP, FL("Unable to change timer"));
return;
}
break;
case eLIM_DEAUTH_ACK_TIMER:
if (tx_timer_deactivate(&pMac->lim.limTimers.gLimDeauthAckTimer)
!= TX_SUCCESS) {
/**
** Could not deactivate Join Failure
** timer. Log error.
**/
lim_log(pMac, LOGP,
FL("Unable to deactivate Deauth ack timer"));
return;
}
val = 1000;
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change(&pMac->lim.limTimers.gLimDeauthAckTimer,
val, 0) != TX_SUCCESS) {
/**
* Could not change Join Failure
* timer. Log error.
*/
lim_log(pMac, LOGP, FL("Unable to change timer"));
return;
}
break;
case eLIM_INSERT_SINGLESHOT_NOA_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer) !=
TX_SUCCESS) {
/**
** Could not deactivate SingleShot NOA Insert
** timer. Log error.
**/
lim_log(pMac, LOGP,
FL
("Unable to deactivate SingleShot NOA Insert timer"));
return;
}
val = LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE;
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change
(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer, val,
0) != TX_SUCCESS) {
/**
* Could not change Single Shot NOA Insert
* timer. Log error.
*/
lim_log(pMac, LOGP, FL("Unable to change timer"));
return;
}
break;
default:
/* Invalid timerId. Log error */
break;
}
} /****** end lim_deactivate_and_change_timer() ******/
/**
* lim_deactivate_and_change_per_sta_id_timer()
*
*
* @brief: This function is called to deactivate and change a per STA timer
* for future re-activation
*
***LOGIC:
*
***ASSUMPTIONS:
* NA
*
* @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index.
*
* @param pMac - Pointer to Global MAC structure
* @param timerId - enum of timer to be deactivated and changed
* This enum is defined in lim_utils.h file
* @param staId - staId
*
* @return None
*/
void
lim_deactivate_and_change_per_sta_id_timer(tpAniSirGlobal pMac, uint32_t timerId,
uint16_t staId)
{
uint32_t val;
MTRACE(mac_trace
(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, timerId));
switch (timerId) {
case eLIM_CNF_WAIT_TIMER:
if (tx_timer_deactivate
(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId])
!= TX_SUCCESS) {
lim_log(pMac, LOGP,
FL("unable to deactivate CNF wait timer"));
}
/* Change timer to reactivate it in future */
if (wlan_cfg_get_int(pMac, WNI_CFG_WT_CNF_TIMEOUT,
&val) != eSIR_SUCCESS) {
/**
* Could not get cnf timeout value
* from CFG. Log error.
*/
lim_log(pMac, LOGP,
FL("could not retrieve cnf timeout value"));
}
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change
(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId], val,
val) != TX_SUCCESS) {
/* Could not change cnf timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("unable to change cnf wait timer"));
}
break;
case eLIM_AUTH_RSP_TIMER:
{
tLimPreAuthNode *pAuthNode;
pAuthNode =
lim_get_pre_auth_node_from_index(pMac,
&pMac->lim.
gLimPreAuthTimerTable,
staId);
if (pAuthNode == NULL) {
lim_log(pMac, LOGP,
FL("Invalid Pre Auth Index passed :%d"),
staId);
break;
}
if (tx_timer_deactivate(&pAuthNode->timer) !=
TX_SUCCESS) {
/* Could not deactivate auth response timer. */
/* Log error */
lim_log(pMac, LOGP,
FL
("unable to deactivate auth response timer"));
}
/* Change timer to reactivate it in future */
if (wlan_cfg_get_int
(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT,
&val) != eSIR_SUCCESS) {
/**
* Could not get auth rsp timeout value
* from CFG. Log error.
*/
lim_log(pMac, LOGP,
FL
("could not retrieve auth response timeout value"));
}
val = SYS_MS_TO_TICKS(val);
if (tx_timer_change(&pAuthNode->timer, val, 0) !=
TX_SUCCESS) {
/* Could not change auth rsp timer. */
/* Log error */
lim_log(pMac, LOGP,
FL("unable to change auth rsp timer"));
}
}
break;
default:
/* Invalid timerId. Log error */
break;
}
}
/**
* lim_activate_cnf_timer()
*
***FUNCTION:
* This function is called to activate a per STA timer
*
***LOGIC:
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure
* @param StaId - staId
*
* @return None
*/
void lim_activate_cnf_timer(tpAniSirGlobal pMac, uint16_t staId,
tpPESession psessionEntry)
{
MTRACE(mac_trace
(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
eLIM_CNF_WAIT_TIMER));
pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId =
psessionEntry->peSessionId;
if (tx_timer_activate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId])
!= TX_SUCCESS) {
lim_log(pMac, LOGP, FL("could not activate cnf wait timer"));
}
}
/**
* lim_activate_auth_rsp_timer()
*
***FUNCTION:
* This function is called to activate a per STA timer
*
***LOGIC:
*
***ASSUMPTIONS:
* NA
*
***NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure
* @param id - id
*
* @return None
*/
void lim_activate_auth_rsp_timer(tpAniSirGlobal pMac, tLimPreAuthNode *pAuthNode)
{
MTRACE(mac_trace
(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION,
eLIM_AUTH_RESP_TIMER));
if (tx_timer_activate(&pAuthNode->timer) != TX_SUCCESS) {
/* / Could not activate auth rsp timer. */
/* Log error */
lim_log(pMac, LOGP, FL("could not activate auth rsp timer"));
}
}
/**
* lim_send_disassoc_frame_threshold_handler()
*
***FUNCTION:
* This function reloads the credit to the send disassociate frame bucket
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
* NA
*
* @param
*
* @return None
*/
void lim_send_disassoc_frame_threshold_handler(void *pMacGlobal, uint32_t param)
{
tSirMsgQ msg;
uint32_t statusCode;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
msg.type = SIR_LIM_HASH_MISS_THRES_TIMEOUT;
msg.bodyval = 0;
msg.bodyptr = NULL;
if ((statusCode = lim_post_msg_api(pMac, &msg)) != eSIR_SUCCESS)
lim_log(pMac, LOGE,
FL("posting to LIM failed, reason=%d"), statusCode);
}
/**
* limAssocCnfWaitTmerHandler()
*
***FUNCTION:
* This function post a message to send a disassociate frame out.
*
***LOGIC:
*
***ASSUMPTIONS:
*
***NOTE:
* NA
*
* @param
*
* @return None
*/
void lim_cnf_wait_tmer_handler(void *pMacGlobal, uint32_t param)
{
tSirMsgQ msg;
uint32_t statusCode;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
msg.type = SIR_LIM_CNF_WAIT_TIMEOUT;
msg.bodyval = (uint32_t) param;
msg.bodyptr = NULL;
if ((statusCode = lim_post_msg_api(pMac, &msg)) != eSIR_SUCCESS)
lim_log(pMac, LOGE,
FL("posting to LIM failed, reason=%d"), statusCode);
}
void lim_channel_switch_timer_handler(void *pMacGlobal, uint32_t param)
{
tSirMsgQ msg;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
PELOG1(lim_log(pMac, LOG1,
FL("ChannelSwitch Timer expired. Posting msg to LIM "));
)
msg.type = SIR_LIM_CHANNEL_SWITCH_TIMEOUT;
msg.bodyval = (uint32_t) param;
msg.bodyptr = NULL;
lim_post_msg_api(pMac, &msg);
}
void lim_quiet_timer_handler(void *pMacGlobal, uint32_t param)
{
tSirMsgQ msg;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
msg.type = SIR_LIM_QUIET_TIMEOUT;
msg.bodyval = (uint32_t) param;
msg.bodyptr = NULL;
PELOG1(lim_log(pMac, LOG1, FL("Post SIR_LIM_QUIET_TIMEOUT msg. "));)
lim_post_msg_api(pMac, &msg);
}
void lim_quiet_bss_timer_handler(void *pMacGlobal, uint32_t param)
{
tSirMsgQ msg;
tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
msg.type = SIR_LIM_QUIET_BSS_TIMEOUT;
msg.bodyval = (uint32_t) param;
msg.bodyptr = NULL;
PELOG1(lim_log(pMac, LOG1, FL("Post SIR_LIM_QUIET_BSS_TIMEOUT msg. "));)
lim_post_msg_api(pMac, &msg);
}