From 49275561ed49d93097a7f300608dc270e010e005 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Tue, 13 Sep 2016 12:35:22 +0530 Subject: [PATCH] qcacld-3.0: Ignore beacon miss if CSA is in progress qcacld-2.0 to qcacld-3.0 propagation In case if CSA is in progress and beacon missed is received the session is disconnected. Now if STA tries to connect to new AP and at the same time CSA timer expires then tries to switch channel. As old session is deleted this switch channel fails as channel info is invalid. This also leads to LIM state change and thus the roam command is not removed from active command list. To fix this: - Ignore beacon miss if CSA is in progress - In CSA timer add check to ensure that channel change is for current session. Change-Id: Icbb80394e4870ccae19782ee17e37465020e93f9 CRs-Fixed: 1060378 --- .../mac/src/pe/lim/lim_link_monitoring_algo.c | 10 ++++++- core/mac/src/pe/lim/lim_utils.c | 27 ++++++++++++++----- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/core/mac/src/pe/lim/lim_link_monitoring_algo.c b/core/mac/src/pe/lim/lim_link_monitoring_algo.c index 923d9a2d4ffd..9d7b9fe9d936 100644 --- a/core/mac/src/pe/lim/lim_link_monitoring_algo.c +++ b/core/mac/src/pe/lim/lim_link_monitoring_algo.c @@ -457,7 +457,15 @@ void lim_handle_heart_beat_failure(tpAniSirGlobal mac_ctx, if (!mac_ctx->sys.gSysEnableLinkMonitorMode) return; - /* Beacon frame not received within heartbeat timeout. */ + /* Ignore HB if channel switch is in progress */ + if (session->gLimSpecMgmt.dot11hChanSwState == + eLIM_11H_CHANSW_RUNNING) { + lim_log(mac_ctx, LOGE, + FL("Ignore Heartbeat failure as Channel switch is in progress")); + session->pmmOffloadInfo.bcnmiss = false; + return; + } + /* Beacon frame not received within heartbeat timeout. */ lim_log(mac_ctx, LOGW, FL("Heartbeat Failure")); mac_ctx->lim.gLimHBfailureCntInLinkEstState++; diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 1d8edcdb4e26..420f7c4e30aa 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -2013,17 +2013,23 @@ void lim_process_channel_switch_timeout(tpAniSirGlobal pMac) psessionEntry = pe_find_session_by_session_id(pMac, pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId); if (psessionEntry == NULL) { - lim_log(pMac, LOGP, + lim_log(pMac, LOGE, FL("Session Does not exist for given sessionID")); return; } if (!LIM_IS_STA_ROLE(psessionEntry)) { - PELOGW(lim_log - (pMac, LOGW, + lim_log(pMac, LOGW, "Channel switch can be done only in STA role, Current Role = %d", GET_LIM_SYSTEM_ROLE(psessionEntry)); - ) + return; + } + + if (psessionEntry->gLimSpecMgmt.dot11hChanSwState != + eLIM_11H_CHANSW_RUNNING) { + lim_log(pMac, LOGW, + FL("Channel switch timer should not have been running in state %d"), + psessionEntry->gLimSpecMgmt.dot11hChanSwState); return; } @@ -2048,15 +2054,22 @@ void lim_process_channel_switch_timeout(tpAniSirGlobal pMac) return; } - /* If the channel-list that AP is asking us to switch is invalid, + /* + * If the channel-list that AP is asking us to switch is invalid * then we cannot switch the channel. Just disassociate from AP. * We will find a better AP !!! */ - lim_tear_down_link_with_ap(pMac, + if ((psessionEntry->limMlmState == + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) { + lim_log(pMac, LOGE, FL("Invalid channel! Disconnect")); + lim_tear_down_link_with_ap(pMac, pMac->lim.limTimers. gLimChannelSwitchTimer.sessionId, eSIR_MAC_UNSPEC_FAILURE_REASON); - return; + return; + } } lim_covert_channel_scan_type(pMac, psessionEntry->currentOperChannel, false);