Merge "wlan: At very low RSSI increase throttle down of TX traffic" into wlan-driver.lnx.1.0-dev.1.0
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 04ebf82..5a52a2c 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -3043,6 +3043,15 @@
#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX (100)
#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT (10)
+/*
+ * gEnableLFRMBB is used to disable/enable LFR Make before Break
+ * 1: Enable LFR Make before Break
+ * 0: Disable LFR Make before Break
+ */
+#define CFG_ENABLE_LFR_MBB "gEnableLFRMBB"
+#define CFG_ENABLE_LFR_MBB_MIN (0)
+#define CFG_ENABLE_LFR_MBB_MAX (1)
+#define CFG_ENABLE_LFR_MBB_DEFAULT (0)
/*---------------------------------------------------------------------------
Type declarations
@@ -3274,6 +3283,11 @@
v_U32_t PERtimerThreshold;
v_U32_t PERroamRxPktsThreshold;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
hdd_wmm_classification_t PktClassificationBasis; // DSCP or 802.1Q
v_BOOL_t bImplicitQosEnabled;
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 956f5fb..c485114 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -2877,6 +2877,15 @@
CFG_PER_ROAM_BAD_RSSI_MAX),
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ REG_VARIABLE(CFG_ENABLE_LFR_MBB, WLAN_PARAM_Integer,
+ hdd_config_t, enable_lfr_mbb,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ENABLE_LFR_MBB_DEFAULT,
+ CFG_ENABLE_LFR_MBB_MIN,
+ CFG_ENABLE_LFR_MBB_MAX ),
+#endif
+
REG_VARIABLE( CFG_ENABLE_ADAPT_RX_DRAIN_NAME, WLAN_PARAM_Integer,
hdd_config_t, fEnableAdaptRxDrain,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK ,
@@ -4530,6 +4539,13 @@
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
"Name = [gEnableSapInternalRestart] Value = [%u] ",
pHddCtx->cfg_ini->sap_internal_restart);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [gEnableLFRMBB] Value = [%u] ",
+ pHddCtx->cfg_ini->enable_lfr_mbb);
+#endif
+
}
@@ -6412,6 +6428,11 @@
smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = 0;
}
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ smeConfig->csrConfig.enable_lfr_mbb = pConfig->enable_lfr_mbb;
+#endif
+
#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
smeConfig->csrConfig.neighborRoamConfig.nNeighborReassocRssiThreshold = pConfig->nNeighborReassocRssiThreshold;
smeConfig->csrConfig.neighborRoamConfig.nNeighborLookupRssiThreshold = pConfig->nNeighborLookupRssiThreshold;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 71365ea..d58daae 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -20059,6 +20059,12 @@
buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
+ if (buf_len > sizeof(*hb_params)) {
+ hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
+ buf_len);
+ return -ERANGE;
+ }
+
hb_params_temp =(tSirLPHBReq *)buf;
if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
(hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 0d93f1c..d63d73e 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -4450,6 +4450,14 @@
return 0;
}
+ if (wrqu->data.length > DOT11F_IE_RSN_MAX_LEN)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: WPARSN Ie input length is more than max[%d]", __func__,
+ wrqu->data.length);
+ return -EINVAL;
+ }
+
switch (genie[0])
{
case DOT11F_EID_WPA:
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index 8197357..ddfbc23 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -230,6 +230,11 @@
TX_TIMER gLimFTPreAuthRspTimer;
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ TX_TIMER glim_pre_auth_mbb_rsp_timer;
+ TX_TIMER glim_reassoc_mbb_rsp_timer;
+#endif
+
#ifdef FEATURE_WLAN_ESE
TX_TIMER gLimEseTsmTimer;
#endif
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 42b4ffc..3f8edad 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -6338,4 +6338,30 @@
void * tsf_rsp_cb_ctx;
}tSirCapTsfParams,*tpSirCapTsfParams;
+#ifdef WLAN_FEATURE_LFR_MBB
+
+/**
+ * enum csr_roam_op_code - Operation to be done by the callback.
+ * @SIR_ROAMING_DEREGISTER_STA: Deregister the old STA after roaming.
+ * @SIR_STOP_ROAM_OFFLOAD_SCAN : sends RSO stop
+ * @SIR_PREPARE_REASSOC_REQ: prepares reassoc request
+ */
+enum csr_roam_op_code {
+ SIR_ROAMING_DEREGISTER_STA,
+ SIR_STOP_ROAM_OFFLOAD_SCAN,
+ SIR_PREPARE_REASSOC_REQ,
+};
+
+/**
+ * enum sir_roam_cleanup_type - Type of cleanup needs to be performed.
+ * @SIR_MBB_DISCONNECTED: Entire CSR cleanup for connected AP
+ * needs to be performed
+ * @SIR_MBB_CONNECTED: No need to perform CSR cleanup for connected AP.
+ */
+enum sir_roam_cleanup_type {
+ SIR_MBB_DISCONNECTED,
+ SIR_MBB_CONNECTED,
+};
+#endif
+
#endif /* __SIR_API_H */
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 718af27..6ed2bb0 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -389,6 +389,12 @@
eWNI_SME_REGISTER_MGMT_FRAME_CB,
eWNI_SME_CAP_TSF_REQ,
eWNI_SME_GET_TSF_REQ,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ,
+ eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP,
+#endif
+
eWNI_SME_MSG_TYPES_END
};
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 9752eb7..17be814 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -151,6 +151,9 @@
*/
SAP_OFFLOADS = 65,
SAP_BUFF_ALLOC = 66,
+#ifdef WLAN_FEATURE_LFR_MBB
+ MAKE_BEFORE_BREAK = 67,
+#endif
NUD_DEBUG = 68,
//MAX_FEATURE_SUPPORTED = 128
} placeHolderInCapBitmap;
@@ -175,6 +178,11 @@
eSIR_LINK_FINISH_CAL_STATE = 13,
eSIR_LINK_LISTEN_STATE = 14,
eSIR_LINK_SEND_ACTION_STATE = 15,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ eSIR_LINK_PRE_AUTH_REASSOC_STATE = 17,
+#endif
+
} tSirLinkState;
@@ -895,6 +903,11 @@
#define SIR_LIM_DEAUTH_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x27)
#define SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x28)
+#ifdef WLAN_FEATURE_LFR_MBB
+#define SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x29)
+#define SIR_LIM_REASSOC_MBB_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2A)
+#endif
+
#define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (SIR_LIM_TIMEOUT_MSG_START + 0x2C)
#define SIR_LIM_AUTH_RETRY_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2D)
diff --git a/CORE/MAC/src/pe/include/limFT.h b/CORE/MAC/src/pe/include/limFT.h
index d750849..bf4dd64 100644
--- a/CORE/MAC/src/pe/include/limFT.h
+++ b/CORE/MAC/src/pe/include/limFT.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -52,6 +52,7 @@
extern int limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
extern void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
tpPESession psessionEntry);
+void limFTSetupAuthSession(tpAniSirGlobal pMac, tpPESession psessionEntry);
void limPerformPostFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
tpPESession psessionEntry);
void limFTResumeLinkCb(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data);
diff --git a/CORE/MAC/src/pe/include/limFTDefs.h b/CORE/MAC/src/pe/include/limFTDefs.h
index 97625a3..02b9d5f 100644
--- a/CORE/MAC/src/pe/include/limFTDefs.h
+++ b/CORE/MAC/src/pe/include/limFTDefs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -81,6 +81,10 @@
tANI_U8 ft_ies[MAX_FTIE_SIZE];
tANI_U16 ric_ies_length;
tANI_U8 ric_ies[MAX_FTIE_SIZE];
+#ifdef WLAN_FEATURE_LFR_MBB
+ enum sir_roam_cleanup_type reason;
+ tCsrRoamInfo *roam_info;
+#endif
} tSirFTPreAuthRsp, *tpSirFTPreAuthRsp;
/*--------------------------------------------------------------------------
diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h
index e517bfb..f00449c 100644
--- a/CORE/MAC/src/pe/include/limSession.h
+++ b/CORE/MAC/src/pe/include/limSession.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
diff --git a/CORE/MAC/src/pe/include/lim_mbb.h b/CORE/MAC/src/pe/include/lim_mbb.h
new file mode 100644
index 0000000..770263e
--- /dev/null
+++ b/CORE/MAC/src/pe/include/lim_mbb.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+void lim_process_preauth_mbb_rsp_timeout(tpAniSirGlobal mac);
+void lim_process_pre_auth_reassoc_req(tpAniSirGlobal mac, tpSirMsgQ msg);
+void lim_handle_pre_auth_mbb_rsp(tpAniSirGlobal mac,
+ tSirRetStatus status, tpPESession session_entry);
+void lim_process_reassoc_mbb_rsp_timeout(tpAniSirGlobal mac);
+void lim_handle_reassoc_mbb_fail(tpAniSirGlobal mac,
+ tpPESession session_entry);
+void lim_handle_reassoc_mbb_success(tpAniSirGlobal mac,
+ tpPESession session_entry, tpSirAssocRsp assoc_rsp, tpDphHashNode sta_ds);
+void lim_process_sta_mlm_del_sta_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ lim_msg, tpPESession session_entry);
+void lim_process_sta_mlm_del_bss_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ lim_msg, tpPESession session_entry);
+void lim_process_sta_mlm_add_bss_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ limMsgQ,tpPESession session_entry);
+void lim_process_sta_mlm_add_sta_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ limMsgQ,tpPESession session_entry);
+eAniBoolean lim_is_mbb_reassoc_in_progress(tpAniSirGlobal mac,
+ tpPESession session_entry);
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.h b/CORE/MAC/src/pe/lim/limAssocUtils.h
index d44afc5..8b4705a 100644
--- a/CORE/MAC/src/pe/lim/limAssocUtils.h
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -188,6 +188,7 @@
tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval);
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+tANI_U16 __limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf);
#endif /* __LIM_ASSOC_UTILS_H */
diff --git a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
index 36b7a68..d60902a 100644
--- a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
+++ b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -55,6 +55,9 @@
#endif //FEATURE_WLAN_DIAG_SUPPORT
#include "limSession.h"
#include "limSerDesUtils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
/**
@@ -111,6 +114,15 @@
return;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+ {
+ limLog(pMac, LOGE,
+ FL("Ignore delete sta as LFR MBB in progress"));
+ return;
+ }
+#endif
+
switch(pMsg->reasonCode)
{
case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE:
@@ -474,6 +486,15 @@
/* Ensure HB Status for the session has been reseted */
psessionEntry->LimHBFailureStatus = eANI_BOOLEAN_FALSE;
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+ {
+ limLog(pMac, LOGE,
+ FL("Ignore Heartbeat failure as LFR MBB in progress"));
+ return;
+ }
+#endif
+
if (((psessionEntry->limSystemRole == eLIM_STA_ROLE)||
(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
(psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)&&
diff --git a/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index ab54e41..8b402d1 100644
--- a/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -68,6 +68,10 @@
#endif
#include "wlan_qct_wda.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
#define BA_DEFAULT_TX_BUFFER_SIZE 64
@@ -169,7 +173,16 @@
tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
limLog(pMac, LOG1, FL(" ENTER"));
-
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry))
+ {
+ limLog(pMac, LOGE,
+ FL("Ignore channel switch as LFR MBB in progress"));
+ return eSIR_SUCCESS;
+ }
+#endif
+
/*If channel switch is already running and it is on a different session, just return*/
/*This need to be removed for MCC */
if( limIsChanSwitchRunning (pMac) &&
diff --git a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
index d08df5b..6ff2251 100644
--- a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -56,6 +56,10 @@
#include "eseApi.h"
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
extern tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry);
@@ -636,6 +640,11 @@
limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER);
else // Stop Reassociation failure timer
{
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_MBB_RSP_TIMER);
+#endif
+
#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
pMac->lim.reAssocRetryAttempt = 0;
if ((NULL != pMac->lim.pSessionEntry) && (NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq))
@@ -644,7 +653,10 @@
pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL;
}
#endif
- limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+ /* Dactivate timer when it is not LFR MBB */
+ if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
}
if (pAssocRsp->statusCode != eSIR_MAC_SUCCESS_STATUS)
@@ -668,6 +680,9 @@
}else
mlmAssocCnf.resultCode = eSIR_SME_ASSOC_REFUSED;
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ goto assocReject;
+
// Delete Pre-auth context for the associated BSS
if (limSearchPreAuthList(pMac, pHdr->sa))
limDeletePreAuthNode(pMac, pHdr->sa);
@@ -696,18 +711,22 @@
* assoc/reassoc response
* NOTE: for BTAMP case, it is being handled in limProcessMlmAssocReq
*/
- if (!((psessionEntry->bssType == eSIR_BTAMP_STA_MODE) ||
- ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) &&
- (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))))
- {
- if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, psessionEntry->bssId,
- psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ if (!((psessionEntry->bssType == eSIR_BTAMP_STA_MODE) ||
+ ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) &&
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))))
+ {
+ if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE,
+ psessionEntry->bssId,
+ psessionEntry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS)
{
PELOGE(limLog(pMac, LOGE, FL("Set link state to POSTASSOC failed"));)
vos_mem_free(pBeaconStruct);
vos_mem_free(pAssocRsp);
return;
}
+ }
}
if (subType == LIM_REASSOC)
{
@@ -776,6 +795,21 @@
goto assocReject;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ limLog(pMac, LOG1, FL("Reassoc success for LFR MBB in state %d"),
+ psessionEntry->limMlmState);
+ if (psessionEntry->limMlmState ==
+ eLIM_MLM_WT_REASSOC_RSP_STATE) {
+ lim_handle_reassoc_mbb_success(pMac, psessionEntry,
+ pAssocRsp, pStaDs);
+ return;
+ }
+ goto assocReject;
+ }
+#endif
+
+
#if defined(WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
if (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)
{
@@ -962,6 +996,14 @@
}
#endif /* WLAN_FEATURE_VOWIFI_11R */
} else {
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_handle_reassoc_mbb_fail(pMac, psessionEntry);
+ vos_mem_free(pBeaconStruct);
+ vos_mem_free(pAssocRsp);
+ return;
+ }
+#endif
limRestorePreReassocState( pMac,
eSIR_SME_REASSOC_REFUSED, mlmAssocCnf.protStatusCode,psessionEntry);
}
diff --git a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
index 09bb745..83dd917 100644
--- a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -51,6 +51,9 @@
#include "limFT.h"
#endif
#include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
/**
@@ -1873,15 +1876,33 @@
limLog(pMac, LOG1, FL("Pre-Auth response received from neighbor"));
limLog(pMac, LOG1, FL("Pre-Auth done state"));
#endif
+
+ limLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
// Stopping timer now, that we have our unicast from the AP
// of our choice.
- limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+ if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb)
+ limDeactivateAndChangeTimer(pMac, eLIM_PREAUTH_MBB_RSP_TIMER);
+#endif
// Save off the auth resp.
if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, &rxAuthFrame) != eSIR_SUCCESS))
{
limLog(pMac, LOGE, FL("failed to convert Auth frame to struct"));
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_handle_pre_auth_mbb_rsp(pMac, eSIR_FAILURE, psessionEntry);
+ return eSIR_FAILURE;
+ }
+#endif
+
limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
return eSIR_FAILURE;
}
@@ -1921,6 +1942,13 @@
break;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_handle_pre_auth_mbb_rsp(pMac, ret_status, psessionEntry);
+ return ret_status;
+ }
+#endif
+
// Send the Auth response to SME
limHandleFTPreAuthRsp(pMac, ret_status, pBody, frameLen, psessionEntry);
diff --git a/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
index a7d4df8..ef1056e 100644
--- a/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -36,6 +36,9 @@
#include "limSerDesUtils.h"
#include "schApi.h"
#include "limSendMessages.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
@@ -77,7 +80,6 @@
pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
-
if ((eLIM_STA_ROLE == psessionEntry->limSystemRole) && (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))
{
/*Every 15th deauth frame will be logged in kmsg*/
@@ -229,6 +231,14 @@
{
pRoamSessionEntry = peFindSessionByBssid(pMac, psessionEntry->limReAssocbssId, &roamSessionId);
}
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) {
+ limLog(pMac, LOGE, FL("Ignore Deauth frame as LFR MBB in progress"));
+ return;
+ }
+#endif
+
if (limIsReassocInProgress(pMac,psessionEntry) || limIsReassocInProgress(pMac,pRoamSessionEntry)) {
if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) {
PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from unknown/different "
diff --git a/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c b/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
index 6483854..88585ab 100644
--- a/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -49,6 +49,9 @@
#include "limSerDesUtils.h"
#include "limSendMessages.h"
#include "schApi.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
/**
@@ -84,7 +87,6 @@
pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
-
if (limIsGroupAddr(pHdr->sa))
{
// Received Disassoc frame from a BC/MC address
@@ -160,6 +162,13 @@
return;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) {
+ limLog(pMac, LOGE, FL("Ignore Disassoc frame as LFR MBB in progress"));
+ return;
+ }
+#endif
+
/** If we are in the Wait for ReAssoc Rsp state */
if (limIsReassocInProgress(pMac,psessionEntry)) {
/** If we had received the DisAssoc from,
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index abc8bad..15d6c64 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -776,6 +776,7 @@
tANI_U8 sessionId;
tAniBool isFrmFt = FALSE;
tANI_U16 fcOffset = WLANHAL_RX_BD_HEADER_SIZE;
+ tANI_S8 pe_sessionid = -1;
*pDeferMsg= false;
limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo);
@@ -875,6 +876,24 @@
pMac->PERroamCandidatesCnt = 0;
}
+ pe_sessionid = limGetInfraSessionId(pMac);
+ if (pe_sessionid != -1) {
+ psessionEntry = peFindSessionBySessionId(pMac, pe_sessionid);
+ if (psessionEntry != NULL)
+ {
+ if ((psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) ||
+ (psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE))
+ {
+ limLog(pMac, LOG1,
+ FL("Drop candidate ind as deauth/disassoc in progress"));
+ goto end;
+ }
+ }
+ }
+ else
+ limLog(pMac, LOGE,
+ FL("session id doesn't exist for infra"));
+
//send a session 0 for now - TBD
limSendSmeCandidateFoundInd(pMac, 0);
goto end;
@@ -1681,6 +1700,9 @@
case eWNI_SME_FT_PRE_AUTH_REQ:
case eWNI_SME_FT_AGGR_QOS_REQ:
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ:
+#endif
case eWNI_SME_ADD_STA_SELF_REQ:
case eWNI_SME_DEL_STA_SELF_REQ:
case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
@@ -1986,6 +2008,10 @@
case SIR_LIM_DEAUTH_ACK_TIMEOUT:
case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
case SIR_LIM_AUTH_RETRY_TIMEOUT:
+#ifdef WLAN_FEATURE_LFR_MBB
+ case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+ case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+#endif
// These timeout messages are handled by MLM sub module
limProcessMlmReqMessages(pMac,
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
index d0eab9b..2c9a860 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -59,6 +59,9 @@
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
#include "vos_diag_core_log.h"
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
// MLM REQ processing function templates
@@ -155,6 +158,14 @@
#ifdef WLAN_FEATURE_VOWIFI_11R
case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:limProcessFTPreauthRspTimeout(pMac); break;
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+ lim_process_preauth_mbb_rsp_timeout(pMac);
+ break;
+ case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+ lim_process_reassoc_mbb_rsp_timeout(pMac);
+ break;
+#endif
case SIR_LIM_REMAIN_CHN_TIMEOUT: limProcessRemainOnChnTimeout(pMac); break;
case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT:
limProcessInsertSingleShotNOATimeout(pMac); break;
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index 98cdc5c..feb52ac 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -61,6 +61,10 @@
#include "wlan_qct_wda.h"
#include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
static void limHandleSmeJoinResult(tpAniSirGlobal, tSirResultCodes, tANI_U16,tpPESession);
static void limHandleSmeReaasocResult(tpAniSirGlobal, tSirResultCodes, tANI_U16, tpPESession);
void limProcessMlmScanCnf(tpAniSirGlobal, tANI_U32 *);
@@ -1981,6 +1985,12 @@
limProcessBtAmpApMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
return;
}
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_process_sta_mlm_add_sta_rsp_mbb(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+#endif
limProcessStaMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
}
void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry)
@@ -2158,6 +2168,13 @@
tpDphHashNode pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_process_sta_mlm_del_bss_rsp_mbb(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+#endif
+
if (NULL == pDelBssParams)
{
limLog( pMac, LOGE, FL( "Invalid body pointer in message"));
@@ -2431,6 +2448,13 @@
tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
tpDphHashNode pStaDs = NULL;
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_process_sta_mlm_del_sta_rsp_mbb(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+#endif
+
if(NULL == pDelStaParams )
{
limLog( pMac, LOGE, FL( "Encountered NULL Pointer" ));
@@ -3430,9 +3454,16 @@
else
limProcessApMlmAddBssRsp( pMac,limMsgQ);
}
- else
+ else {
+#ifdef WLAN_FEATURE_LFR_MBB
+ if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ lim_process_sta_mlm_add_bss_rsp_mbb(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+#endif
/* Called while processing assoc response */
limProcessStaMlmAddBssRsp( pMac, limMsgQ,psessionEntry);
+ }
}
if(limIsInMCC(pMac))
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index d91635a..1a26981 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -76,6 +76,10 @@
#include <limFT.h>
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "lim_mbb.h"
+#endif
+
#define JOIN_FAILURE_TIMEOUT 1000 // in msecs
/* This overhead is time for sending NOA start to host in case of GO/sending NULL data & receiving ACK
@@ -243,7 +247,7 @@
* @return Total IE length
*/
-static tANI_U16
+tANI_U16
__limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf)
{
tANI_U16 len = 0;
@@ -5907,6 +5911,13 @@
break;
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ:
+ lim_process_pre_auth_reassoc_req(pMac, pMsg);
+ bufConsumed = FALSE;
+ break;
+#endif
+
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
case eWNI_SME_ESE_ADJACENT_AP_REPORT:
limProcessAdjacentAPRepMsg ( pMac, pMsgBuf );
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
index 85c577b..44bebf2 100644
--- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -54,7 +54,7 @@
#include "limSendSmeRspMessages.h"
#include "limIbssPeerMgmt.h"
#include "limSessionUtils.h"
-
+#include "lim_mbb.h"
/**
* limSendSmeRsp()
@@ -2815,10 +2815,8 @@
{
limProcessSmeDelBssRsp(pMac, MsgQ->bodyval,psessionEntry);
}
-
else
limProcessMlmDelBssRsp(pMac,MsgQ,psessionEntry);
-
}
#ifdef WLAN_FEATURE_VOWIFI_11R
diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c
index cbd2e4d..23c53bd 100644
--- a/CORE/MAC/src/pe/lim/limSession.c
+++ b/CORE/MAC/src/pe/lim/limSession.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.c b/CORE/MAC/src/pe/lim/limTimerUtils.c
index 0237271..1e47421 100644
--- a/CORE/MAC/src/pe/lim/limTimerUtils.c
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -64,6 +64,10 @@
convert ACTIVE DFS channel to DFS channels */
#define ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT 1000
+#ifdef WLAN_FEATURE_LFR_MBB
+#define PREAUTH_REASSOC_TIMEOUT 500
+#endif
+
/**
* limCreateTimers()
*
@@ -624,6 +628,34 @@
}
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ cfgValue = PREAUTH_REASSOC_TIMEOUT;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.glim_pre_auth_mbb_rsp_timer,
+ "PREAUTH MBB RSP TIMEOUT",
+ limTimerHandler, SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not create PREAUTH_MBB_RSP timer"));
+ goto err_timer;
+ }
+
+ cfgValue = PREAUTH_REASSOC_TIMEOUT;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.glim_reassoc_mbb_rsp_timer,
+ "REASSOC MBB RSP TIMEOUT",
+ limTimerHandler, SIR_LIM_REASSOC_MBB_RSP_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not create REASSOC_MBB_RSP timer"));
+ goto err_timer;
+ }
+#endif
+
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
cfgValue = 5000;
cfgValue = SYS_MS_TO_TICKS(cfgValue);
@@ -712,6 +744,10 @@
tx_timer_delete(&pMac->lim.limTimers.gLimEseTsmTimer);
#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */
tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer);
+#ifdef WLAN_FEATURE_LFR_MBB
+ tx_timer_delete(&pMac->lim.limTimers.glim_pre_auth_mbb_rsp_timer);
+ tx_timer_delete(&pMac->lim.limTimers.glim_reassoc_mbb_rsp_timer);
+#endif
tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
while(((tANI_S32)--i) >= 0)
{
@@ -1730,6 +1766,30 @@
}
break;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eLIM_PREAUTH_MBB_RSP_TIMER:
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ NO_SESSION, eLIM_PREAUTH_MBB_RSP_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.
+ glim_pre_auth_mbb_rsp_timer) != TX_SUCCESS) {
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate preauth response mbb timer"));
+ return;
+ }
+ break;
+ case eLIM_REASSOC_MBB_RSP_TIMER:
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ NO_SESSION, eLIM_REASSOC_MBB_RSP_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.
+ glim_reassoc_mbb_rsp_timer) != TX_SUCCESS) {
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate reassoc response mbb timer"));
+ return;
+ }
+ break;
+#endif
+
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
case eLIM_TSM_TIMER:
if (tx_timer_deactivate(&pMac->lim.limTimers.gLimEseTsmTimer)
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.h b/CORE/MAC/src/pe/lim/limTimerUtils.h
index 1906182..eba64ac 100644
--- a/CORE/MAC/src/pe/lim/limTimerUtils.h
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -77,7 +77,11 @@
eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER,
eLIM_INSERT_SINGLESHOT_NOA_TIMER,
eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE,
- eLIM_AUTH_RETRY_TIMER
+ eLIM_AUTH_RETRY_TIMER,
+#ifdef WLAN_FEATURE_LFR_MBB
+ eLIM_PREAUTH_MBB_RSP_TIMER,
+ eLIM_REASSOC_MBB_RSP_TIMER
+#endif
};
#define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT 500
diff --git a/CORE/MAC/src/pe/lim/limTrace.c b/CORE/MAC/src/pe/lim/limTrace.c
index 662670b..d33a33d 100644
--- a/CORE/MAC/src/pe/lim/limTrace.c
+++ b/CORE/MAC/src/pe/lim/limTrace.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -92,6 +92,10 @@
CASE_RETURN_STRING(eLIM_INSERT_SINGLESHOT_NOA_TIMER);
CASE_RETURN_STRING(eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE);
CASE_RETURN_STRING(eLIM_AUTH_RETRY_TIMER);
+#ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(eLIM_PREAUTH_MBB_RSP_TIMER);
+ CASE_RETURN_STRING(eLIM_REASSOC_MBB_RSP_TIMER);
+#endif
default:
return( "UNKNOWN" );
break;
diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c
index 42fe6cd..abcd9b7 100644
--- a/CORE/MAC/src/pe/lim/limUtils.c
+++ b/CORE/MAC/src/pe/lim/limUtils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -648,6 +648,13 @@
return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT";
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
+ return "SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT";
+ case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
+ return "SIR_LIM_REASSOC_MBB_RSP_TIMEOUT";
+#endif
+
case SIR_HAL_APP_SETUP_NTF:
return "SIR_HAL_APP_SETUP_NTF";
case SIR_HAL_INITIAL_CAL_FAILED_NTF:
diff --git a/CORE/MAC/src/pe/lim/lim_mbb.c b/CORE/MAC/src/pe/lim/lim_mbb.c
new file mode 100644
index 0000000..e9977b5
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/lim_mbb.c
@@ -0,0 +1,1754 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "aniGlobal.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limFT.h"
+#include "limSendMessages.h"
+#include "limAssocUtils.h"
+#include "limSerDesUtils.h"
+#include "limSmeReqUtils.h"
+#include "limAdmitControl.h"
+#include "sirApi.h"
+#include "rrmApi.h"
+#include "wlan_qct_tl.h"
+
+#define PREAUTH_REASSOC_TIMEOUT 500
+
+void lim_cleanup_connected_ap(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+ tpPESession session_entry);
+
+/**
+ * lim_post_pre_auth_reassoc_rsp() -Posts preauth_reassoc response to SME
+ * @mac: MAC context
+ * @status: status
+ * @session_entry: session entry
+ * @reason: indicates which type of clean up needs to be performed
+ *
+ * This function process preauth_reassoc response to SME
+ */
+void lim_post_pre_auth_reassoc_rsp(tpAniSirGlobal mac,
+ tSirRetStatus status, tpPESession session_entry,
+ enum sir_roam_cleanup_type reason)
+{
+ tpSirFTPreAuthRsp pre_auth_rsp;
+ tSirMsgQ mmh_msg;
+ tANI_U16 rsp_len = sizeof(tSirFTPreAuthRsp);
+ tpPESession session_entry_con_ap;
+ tpDphHashNode sta_ds = NULL;
+
+ pre_auth_rsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rsp_len);
+ if (NULL == pre_auth_rsp) {
+ limLog(mac, LOGE, FL("Failed to allocate memory"));
+ return;
+ }
+
+ limLog(mac, LOG1, FL("reason %d"), reason);
+
+ vos_mem_zero(pre_auth_rsp, rsp_len);
+ pre_auth_rsp->messageType = eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP;
+ pre_auth_rsp->length = (tANI_U16)rsp_len;
+ pre_auth_rsp->status = status;
+ pre_auth_rsp->reason = reason;
+
+ if (session_entry)
+ pre_auth_rsp->smeSessionId = session_entry->smeSessionId;
+
+ /* The bssid of the AP we are sending Auth1 to. */
+ if (mac->ft.ftPEContext.pFTPreAuthReq)
+ sirCopyMacAddr(pre_auth_rsp->preAuthbssId,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId);
+
+ if (status != eSIR_SUCCESS) {
+ limLog(mac, LOG1, FL("Pre-Auth Failed, Cleanup!"));
+ limLog(mac, LOG1, FL("flushing cached packets"));
+ WLANTL_PreAssocForward(false);
+
+ /*
+ * If reason is full clean up, add sme session id that
+ * will be useful in CSR during cleanup.
+ */
+ if (reason == SIR_MBB_DISCONNECTED) {
+ session_entry_con_ap =
+ (tpPESession)mac->ft.ftPEContext.psavedsessionEntry;
+ pre_auth_rsp->smeSessionId =
+ session_entry_con_ap->smeSessionId;
+ }
+ limFTCleanup(mac);
+ }
+
+ if (status == eSIR_SUCCESS) {
+ limLog(mac, LOG1, FL("Success"));
+
+ rsp_len = session_entry->assocReqLen + session_entry->assocRspLen +
+ session_entry->bcnLen;
+
+ pre_auth_rsp->roam_info = vos_mem_malloc(sizeof(tCsrRoamInfo));
+ if (pre_auth_rsp->roam_info == NULL) {
+ limLog(mac, LOGE,
+ FL("Failed to allocate memory for roam info"));
+ return;
+ }
+ vos_mem_set(pre_auth_rsp->roam_info, sizeof(tCsrRoamInfo), 0);
+
+ pre_auth_rsp->roam_info->pbFrames = vos_mem_malloc(rsp_len);
+ if (pre_auth_rsp->roam_info->pbFrames == NULL) {
+ limLog(mac, LOGE,
+ FL("Failed to allocate memory for roam info frames"));
+ return;
+ }
+ vos_mem_set(pre_auth_rsp->roam_info->pbFrames, rsp_len, 0);
+
+
+ pre_auth_rsp->length += rsp_len + sizeof(tCsrRoamInfo);
+
+ session_entry_con_ap =
+ (tpPESession)mac->ft.ftPEContext.psavedsessionEntry;
+ pre_auth_rsp->smeSessionId = session_entry_con_ap->smeSessionId;
+
+ if(session_entry->beacon != NULL) {
+ pre_auth_rsp->roam_info->nBeaconLength = session_entry->bcnLen;
+ vos_mem_copy(pre_auth_rsp->roam_info->pbFrames,
+ session_entry->beacon,
+ session_entry->bcnLen);
+ limLog(mac, LOG1, FL("Beacon len %d"), session_entry->bcnLen);
+
+ vos_mem_free(session_entry->beacon);
+ session_entry->beacon = NULL;
+ }
+
+ if(session_entry->assocReq != NULL) {
+ pre_auth_rsp->roam_info->nAssocReqLength =
+ session_entry->assocReqLen;
+ vos_mem_copy(pre_auth_rsp->roam_info->pbFrames +
+ session_entry->bcnLen,
+ session_entry->assocReq,
+ session_entry->assocReqLen);
+
+ vos_mem_free(session_entry->assocReq);
+ session_entry->assocReq = NULL;
+
+ limLog(mac, LOG1, FL("AssocReq len %d"), session_entry->assocReqLen);
+ }
+
+ if(session_entry->assocRsp != NULL) {
+ pre_auth_rsp->roam_info->nAssocRspLength =
+ session_entry->assocRspLen;
+ vos_mem_copy(pre_auth_rsp->roam_info->pbFrames +
+ session_entry->bcnLen + session_entry->assocReqLen,
+ session_entry->assocRsp,
+ session_entry->assocRspLen);
+
+ vos_mem_free(session_entry->assocRsp);
+ session_entry->assocRsp = NULL;
+
+ limLog(mac, LOG1, FL("AssocRsp len %d"), session_entry->assocRspLen);
+ }
+
+ sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if(NULL == sta_ds) {
+ limLog(mac, LOGE,
+ FL("Unable to get the DPH Hash Entry for AID - %d"),
+ DPH_STA_HASH_INDEX_PEER);
+ return;
+ }
+
+ pre_auth_rsp->roam_info->staId = sta_ds->staIndex;
+ pre_auth_rsp->roam_info->ucastSig = sta_ds->ucUcastSig;
+ pre_auth_rsp->roam_info->bcastSig = sta_ds->ucBcastSig;
+ pre_auth_rsp->roam_info->maxRateFlags =
+ limGetMaxRateFlags(sta_ds, session_entry);
+ }
+
+ mmh_msg.type = pre_auth_rsp->messageType;
+ mmh_msg.bodyptr = pre_auth_rsp;
+ mmh_msg.bodyval = 0;
+
+ limLog(mac, LOG1,
+ FL("Posted Auth Rsp to SME with status of 0x%x"), status);
+
+ limSysProcessMmhMsgApi(mac, &mmh_msg, ePROT);
+}
+
+/*
+ * lim_reassoc_fail_cleanup() -handles cleanup during reassoc failure
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function handles cleanup during reassoc failure
+ */
+void lim_reassoc_fail_cleanup(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession session_entry;
+
+ session_entry = (tpPESession)data;
+
+ if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+ limLog(mac, LOGE, FL("pFTPreAuthReq is NULL"));
+ return;
+ }
+
+ if (dphDeleteHashEntry(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("error deleting hash entry"));
+ }
+
+ /* Delete session as session was created during preauth success */
+ peDeleteSession(mac, session_entry);
+
+ /* Add bss parameter cleanup happens as part of this processing*/
+ if ((status == eHAL_STATUS_MBB_DEL_BSS_FAIL) ||
+ (status == eHAL_STATUS_INVALID_PARAMETER) ||
+ (status == eHAL_STATUS_MBB_ADD_BSS_FAIL))
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_DISCONNECTED);
+ else
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+}
+
+/*
+ * lim_perform_post_reassoc_mbb_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_post_reassoc_mbb_channel_change(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+ tpPESession session_entry_con_ap;
+ tANI_U8 session_id;
+
+ session_entry_con_ap = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+ &session_id);
+ if (session_entry_con_ap == NULL) {
+ limLog(mac, LOGE,
+ FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ peSetResumeChannel(mac, session_entry_con_ap->currentOperChannel, 0);
+ limResumeLink(mac, lim_reassoc_fail_cleanup,
+ (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_reassoc_mbb_fail() -handles reassoc failure
+ * @mac: MAC context
+ * @session_entry: session entry
+ *
+ * This function handles reassoc failure
+ */
+void lim_handle_reassoc_mbb_fail(tpAniSirGlobal mac,
+ tpPESession session_entry)
+{
+ tpPESession session_entry_con_ap;
+ tANI_U8 session_id;
+
+ session_entry_con_ap = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+ &session_id);
+ if (session_entry_con_ap == NULL) {
+ limLog(mac, LOGE,
+ FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ limLog(mac, LOG1, FL("currentOperChannel %d preAuthchannelNum %d"),
+ session_entry_con_ap->currentOperChannel,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);
+
+ /* Restore set link to post assoc for currently connected AP */
+ if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE,
+ session_entry_con_ap->bssId,
+ session_entry_con_ap->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ /* Change channel if required as channel might be changed during preauth */
+ if (session_entry_con_ap->currentOperChannel !=
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ limChangeChannelWithCallback(mac,
+ session_entry_con_ap->currentOperChannel,
+ lim_perform_post_reassoc_mbb_channel_change, NULL, session_entry);
+ } else {
+ /*
+ * Link needs to be resumed as link was suspended
+ * for same channel during preauth.
+ */
+ peSetResumeChannel(mac, session_entry_con_ap->currentOperChannel, 0);
+ limResumeLink(mac, lim_reassoc_fail_cleanup,
+ (tANI_U32 *)session_entry);
+ }
+}
+
+/*
+ * lim_preauth_fail_cleanup() -handles cleanup during preauth failure
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function handles cleanup during reassoc failure
+ */
+void lim_preauth_fail_cleanup(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession session_entry;
+
+ session_entry = (tpPESession)data;
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+}
+
+/*
+ * lim_perform_preauth_mbb_fail_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_preauth_mbb_fail_channel_change(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+ peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+ limResumeLink(mac, lim_preauth_fail_cleanup,
+ (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_preauth_mbb_fail() -handles preauth failure
+ * @mac: MAC context
+ * @session_entry: session entry
+ *
+ * This function handles reassoc failure
+ */
+void lim_handle_preauth_mbb_fail(tpAniSirGlobal mac,
+ tpPESession session_entry)
+{
+ limLog(mac, LOG1, FL("currentOperChannel %d preAuthchannelNum %d"),
+ session_entry->currentOperChannel,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);
+
+ /* Restore set link to post assoc for currently connected AP */
+ if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE,
+ session_entry->bssId,
+ session_entry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ /* Change channel if required as channel might be changed during preauth */
+ if (session_entry->currentOperChannel !=
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ limChangeChannelWithCallback(mac,
+ session_entry->currentOperChannel,
+ lim_perform_preauth_mbb_fail_channel_change, NULL, session_entry);
+ } else {
+ /*
+ * Link needs to be resumed as link was suspended
+ * for same channel during preauth.
+ */
+ peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+ limResumeLink(mac, lim_preauth_fail_cleanup,
+ (tANI_U32 *)session_entry);
+ }
+}
+
+
+/*
+ * lim_del_sta_mbb() -performs del sta
+ * @mac: MAC context
+ * @sta_ds_connected_ap: station entry of connected AP
+ * @resp_reqd: indicates whether response is required or not
+ * @session_entry_connected_ap: session entry of connected AP
+ *
+ * This function performs del sta
+ */
+tSirRetStatus lim_del_sta_mbb(tpAniSirGlobal mac,
+ tpDphHashNode sta_ds_connected_ap,
+ tANI_BOOLEAN resp_reqd,
+ tpPESession session_entry_connected_ap)
+{
+ tpDeleteStaParams del_sta_params;
+ tSirMsgQ msg;
+ tSirRetStatus ret_code;
+
+ del_sta_params = vos_mem_malloc(sizeof(*del_sta_params));
+ if (NULL == del_sta_params) {
+ limLog(mac, LOGE, FL("Unable to allocate memory during DEL_STA" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ vos_mem_zero(del_sta_params, sizeof(*del_sta_params));
+
+ del_sta_params->sessionId = session_entry_connected_ap->peSessionId;
+ del_sta_params->status = eHAL_STATUS_SUCCESS;
+
+#ifdef FEATURE_WLAN_TDLS
+ if(((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)) &&
+ (sta_ds_connected_ap->staType != STA_ENTRY_TDLS_PEER)) ||
+ (eLIM_BT_AMP_STA_ROLE ==
+ GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)))
+#else
+ if((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)) ||
+ (eLIM_BT_AMP_STA_ROLE ==
+ GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)))
+#endif
+ del_sta_params->staIdx = session_entry_connected_ap->staId;
+ else
+ del_sta_params->staIdx = sta_ds_connected_ap->staIndex;
+
+ del_sta_params->assocId = sta_ds_connected_ap->assocId;
+ del_sta_params->respReqd = resp_reqd;
+
+ /* Change Mlm state of connected AP to Del sta rsp state */
+ session_entry_connected_ap->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry_connected_ap->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+ msg.type = WDA_DELETE_STA_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = del_sta_params;
+ msg.bodyval = 0;
+
+ limLog(mac, LOG1,
+ FL("sessionId %d staIdx: %d assocId: %d for "MAC_ADDRESS_STR),
+ del_sta_params->sessionId, del_sta_params->staIdx,
+ del_sta_params->assocId,
+ MAC_ADDR_ARRAY(sta_ds_connected_ap->staAddr));
+
+ MTRACE(macTraceMsgTx(mac, session_entry_connected_ap->peSessionId,
+ msg.type));
+
+ ret_code = wdaPostCtrlMsg(mac, &msg);
+ if( eSIR_SUCCESS != ret_code) {
+ if(resp_reqd)
+ SET_LIM_PROCESS_DEFD_MESGS(mac, true);
+ limLog(mac, LOGE,
+ FL("Posting DELETE_STA_REQ failed, reason=%X"), ret_code);
+ vos_mem_free(del_sta_params);
+ }
+
+ return ret_code;
+}
+
+/*
+ * lim_del_bss_mbb() -performs del bss of connected AP
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @bss_idx:BSS index
+ * @session_entry: session entry
+ *
+ * This function performs del bss of connected AP
+ */
+tSirRetStatus lim_del_bss_mbb(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+ tANI_U16 bss_idx,tpPESession session_entry)
+{
+ tpDeleteBssParams delbss_params = NULL;
+ tSirMsgQ msg;
+ tSirRetStatus ret_code = eSIR_SUCCESS;
+
+ delbss_params = vos_mem_malloc(sizeof(tDeleteBssParams));
+ if (NULL == delbss_params) {
+ limLog(mac, LOGE,
+ FL("Unable to allocate memory during del bss" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ vos_mem_set((tANI_U8 *) delbss_params, sizeof(tDeleteBssParams), 0);
+
+ delbss_params->sessionId = session_entry->peSessionId;
+
+ if (sta_ds != NULL) {
+ delbss_params->bssIdx = sta_ds->bssId;
+ sta_ds->valid = 0;
+ sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+ }
+ else
+ delbss_params->bssIdx = bss_idx;
+
+ session_entry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE));
+
+ delbss_params->status= eHAL_STATUS_SUCCESS;
+ delbss_params->respReqd = 1;
+
+ limLog(mac, LOG1, FL("Sessionid %d bss idx: %x BSSID:" MAC_ADDRESS_STR),
+ delbss_params->sessionId, delbss_params->bssIdx,
+ MAC_ADDR_ARRAY(session_entry->bssId));
+
+ /* we need to defer the message until we get the response back from HAL. */
+ SET_LIM_PROCESS_DEFD_MESGS(mac, false);
+
+ msg.type = WDA_DELETE_BSS_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = delbss_params;
+ msg.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+ if(eSIR_SUCCESS != (ret_code = wdaPostCtrlMsg(mac, &msg)))
+ {
+ SET_LIM_PROCESS_DEFD_MESGS(mac, true);
+ limLog(mac, LOGE,
+ FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"), ret_code);
+ vos_mem_free(delbss_params);
+ }
+
+ return ret_code;
+}
+
+/*
+ * lim_add_bss_mbb() -performs add bss of new roamable AP
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @bss_idx:BSS index
+ * @session_entry: session entry
+ *
+ * This function performs add bss of new roamable AP
+ */
+void lim_add_bss_mbb(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+ tpPESession session_entry)
+{
+ tSirMsgQ msg;
+ tSirRetStatus ret_code;
+
+ /* we need to defer the message until we get the response back from HAL. */
+ SET_LIM_PROCESS_DEFD_MESGS(mac, false);
+
+ msg.type = SIR_HAL_ADD_BSS_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = mac->ft.ftPEContext.pAddBssReq;
+ msg.bodyval = 0;
+
+ limLog(mac, LOG1, FL("Sending SIR_HAL_ADD_BSS_REQ"));
+
+ session_entry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
+
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE));
+
+ MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+ ret_code = wdaPostCtrlMsg(mac, &msg);
+ if( eSIR_SUCCESS != ret_code) {
+ vos_mem_free(mac->ft.ftPEContext.pAddBssReq);
+ limLog(mac, LOGE,
+ FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), ret_code);
+ }
+ /* Dont need this anymore */
+ mac->ft.ftPEContext.pAddBssReq = NULL;
+}
+
+tSirRetStatus lim_add_sta_mbb(tpAniSirGlobal mac, tANI_U16 assoc_id,
+ tpPESession session_entry)
+{
+ tpAddStaParams add_sta_params = NULL;
+ tSirMsgQ msg;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ add_sta_params = mac->ft.ftPEContext.pAddStaReq;
+ add_sta_params->assocId = assoc_id;
+
+ msg.type = SIR_HAL_ADD_STA_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = add_sta_params;
+ msg.bodyval = 0;
+
+ limLog(mac, LOG1,
+ FL("Sending SIR_HAL_ADD_STA_REQ. aid %d)"),
+ add_sta_params->assocId);
+
+ session_entry->limPrevMlmState = session_entry->limMlmState;
+ session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE));
+
+ MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type));
+
+ if(eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( mac, &msg))) {
+ limLog(mac, LOGE,
+ FL("Posting ADD_STA_REQ to HAL failed, reason=%X"), retCode);
+ vos_mem_free(add_sta_params);
+ }
+
+ mac->ft.ftPEContext.pAddStaReq = NULL;
+ return retCode;
+}
+
+/*
+ * lim_handle_reassoc_mbb_success() -handles reassoc success
+ * @mac: MAC context
+ * @session_entry: session entry
+ * @assoc_rsp: pointer to assoc response
+ * @sta_ds : station entry
+ *
+ * This function handles reassoc success
+ */
+void lim_handle_reassoc_mbb_success(tpAniSirGlobal mac,
+ tpPESession session_entry, tpSirAssocRsp assoc_rsp, tpDphHashNode sta_ds)
+{
+ tpPESession session_entry_con_ap;
+ tANI_U8 session_id_connected_ap;
+ tpDphHashNode sta_ds_connected_ap;
+ tANI_U16 aid;
+ tSirRetStatus ret_code;
+
+ limUpdateAssocStaDatas(mac, sta_ds, assoc_rsp, session_entry);
+
+ /* Store assigned AID for TIM processing */
+ session_entry->limAID = assoc_rsp->aid & 0x3FFF;
+
+ /* De register STA for currently connected AP */
+ mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+ NULL, NULL, SIR_ROAMING_DEREGISTER_STA);
+
+ mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+ NULL, NULL, SIR_STOP_ROAM_OFFLOAD_SCAN);
+
+ if((session_entry_con_ap = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+ &session_id_connected_ap))== NULL) {
+ limLog(mac, LOGE,
+ FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+ goto end;
+ }
+
+ session_entry->smeSessionId = session_entry_con_ap->smeSessionId;
+
+ sta_ds_connected_ap = dphLookupHashEntry(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId,
+ &aid,
+ &session_entry_con_ap->dph.dphHashTable);
+ if (sta_ds_connected_ap == NULL) {
+ limLog(mac, LOGE,
+ FL("sta_ds NULL for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+ goto end;
+ }
+
+ /*
+ * Change Mlm state of new AP to Del sta rsp state so that
+ * duplicate reassoc response will be dropped.
+ */
+ session_entry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+ /* Delete sta for currently connected AP */
+ ret_code = lim_del_sta_mbb(mac, sta_ds_connected_ap,
+ false, session_entry_con_ap);
+ if (ret_code == eSIR_SUCCESS)
+ return;
+
+end:
+ /* Connected AP lim cleanup.*/
+ lim_cleanup_connected_ap(mac, sta_ds_connected_ap, session_entry_con_ap);
+ /*
+ * eHAL_STATUS_INVALID_PARAMETER is used
+ * so that full cleanup is triggered.
+ */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+ (tANI_U32 *)session_entry);
+}
+
+
+/*
+ * lim_process_preauth_mbb_result() -process pre auth result
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function invokes resume callback
+ */
+static inline void lim_process_preauth_mbb_result(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession session_entry, ft_session_entry;
+ tpDphHashNode sta_ds;
+ tAddBssParams *add_bss_params;
+ tSirSmeJoinReq *reassoc_req;
+ tLimMlmReassocReq *mlm_reassoc_req;
+ tANI_U16 caps;
+ tANI_U16 nSize;
+ tpSirSmeJoinReq pReassocReq = NULL;
+
+ if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+ limLog(mac, LOG1, "Pre-Auth request is NULL!");
+ goto end;
+ }
+
+ session_entry = (tpPESession)data;
+
+ /* Post the FT Pre Auth Response to SME in case of failure*/
+ if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_FAILURE)
+ goto end;
+
+ /* Flow for preauth success */
+ limFTSetupAuthSession(mac, session_entry);
+
+ /*
+ * Prepare reassoc request. Memory allocated for tSirSmeJoinReq
+ *reassoc_req in csr_fill_reassoc_req. Free that memory here.
+ */
+ mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId,
+ mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription,
+ &reassoc_req, SIR_PREPARE_REASSOC_REQ);
+ if (reassoc_req == NULL) {
+ limLog(mac, LOGE,
+ FL("reassoc req is NULL"));
+ goto end;
+ }
+
+ nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8 *) reassoc_req);
+ pReassocReq = vos_mem_malloc(nSize);
+ if ( NULL == pReassocReq )
+ {
+ limLog(mac, LOGE,
+ FL("call to AllocateMemory failed for pReassocReq"));
+ goto end;
+ }
+ vos_mem_set((void *) pReassocReq, nSize, 0);
+ if ((limJoinReqSerDes(mac, (tpSirSmeJoinReq) pReassocReq,
+ (tANI_U8 *) reassoc_req) == eSIR_FAILURE) ||
+ (!limIsSmeJoinReqValid(mac,
+ (tpSirSmeJoinReq) pReassocReq)))
+ {
+ limLog(mac, LOGE,
+ FL("received SME_REASSOC_REQ with invalid data"));
+ goto end;
+ }
+
+ ft_session_entry = mac->ft.ftPEContext.pftSessionEntry;
+
+ ft_session_entry->pLimReAssocReq = pReassocReq;
+ vos_mem_free(reassoc_req);
+
+ add_bss_params = mac->ft.ftPEContext.pAddBssReq;
+
+ mlm_reassoc_req = vos_mem_malloc(sizeof(tLimMlmReassocReq));
+ if (NULL == mlm_reassoc_req) {
+ limLog(mac, LOGE,
+ FL("call to AllocateMemory failed for mlmReassocReq"));
+ goto end;
+ }
+
+ vos_mem_copy(mlm_reassoc_req->peerMacAddr,
+ ft_session_entry->limReAssocbssId,
+ sizeof(tSirMacAddr));
+ mlm_reassoc_req->reassocFailureTimeout = PREAUTH_REASSOC_TIMEOUT;
+
+ if (cfgGetCapabilityInfo(mac, &caps, ft_session_entry) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("could not retrieve Capabilities value"));
+ vos_mem_free(mlm_reassoc_req);
+ goto end;
+ }
+
+ lim_update_caps_info_for_bss(mac, &caps,
+ reassoc_req->bssDescription.capabilityInfo);
+
+ limLog(mac, LOG1, FL("Capabilities info Reassoc: 0x%X"), caps);
+
+ mlm_reassoc_req->capabilityInfo = caps;
+ mlm_reassoc_req->sessionId = ft_session_entry->peSessionId;
+ mlm_reassoc_req->listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+
+ if ((sta_ds = dphAddHashEntry(mac, add_bss_params->bssId,
+ DPH_STA_HASH_INDEX_PEER,
+ &ft_session_entry->dph.dphHashTable)) == NULL) {
+ limLog(mac, LOGE, FL("could not add hash entry at DPH"));
+ limPrintMacAddr(mac, add_bss_params->bssId, LOGE);
+ vos_mem_free(mlm_reassoc_req);
+ goto end;
+ }
+
+ /* Start timer here to handle reassoc timeout */
+ mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId =
+ ft_session_entry->peSessionId;
+
+ MTRACE(macTrace(mac, TRACE_CODE_TIMER_ACTIVATE,
+ session_entry->peSessionId, eLIM_REASSOC_MBB_RSP_TIMER));
+
+ if(TX_SUCCESS !=
+ tx_timer_activate(&mac->lim.limTimers.glim_reassoc_mbb_rsp_timer)) {
+ limLog(mac, LOGE, FL("Reassoc MBB Rsp Timer Start Failed"));
+
+ if (ft_session_entry->pLimReAssocReq) {
+ vos_mem_free(ft_session_entry->pLimReAssocReq);
+ ft_session_entry->pLimReAssocReq = NULL;
+ }
+
+ vos_mem_free(mlm_reassoc_req);
+ goto end;
+ }
+
+ limLog(mac, LOG1, FL("enabling caching"));
+ WLANTL_EnablePreAssocCaching();
+
+ /* To do: Add changes for reassoc fail timer */
+ limSendReassocReqWithFTIEsMgmtFrame(mac,
+ mlm_reassoc_req, ft_session_entry);
+
+ ft_session_entry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+
+ limLog(mac, LOG1, FL("Set the mlm state to %d session=%d"),
+ ft_session_entry->limMlmState, ft_session_entry->peSessionId);
+ return;
+
+end:
+ lim_handle_reassoc_mbb_fail(mac, ft_session_entry);
+}
+
+/*
+ * lim_perform_post_preauth_mbb_channel_change() -invokes resume callback
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ * @session_entry: session entry
+ *
+ * This function invokes resume callback after successful reception of
+ * pre auth
+ */
+static inline
+void lim_perform_post_preauth_mbb_channel_change(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data, tpPESession session_entry)
+{
+ peSetResumeChannel(mac, 0, 0);
+ limResumeLink(mac, lim_process_preauth_mbb_result,
+ (tANI_U32 *)session_entry);
+}
+
+/*
+ * lim_handle_pre_auth_mbb_rsp() -handles preauth response
+ * @mac: MAC context
+ * @status: status of message
+ * @session_entry: session entry
+ *
+ * This function process preauth response
+ */
+void lim_handle_pre_auth_mbb_rsp(tpAniSirGlobal mac,
+ tSirRetStatus status, tpPESession session_entry)
+{
+ tpPESession ft_session_entry;
+ tANI_U8 session_id;
+ tpSirBssDescription bss_description;
+
+ mac->ft.ftPEContext.ftPreAuthStatus = status;
+
+ mac->ft.ftPEContext.saved_auth_rsp_length = 0;
+
+ limLog(mac, LOG1, FL("preauth status %d"),
+ mac->ft.ftPEContext.ftPreAuthStatus);
+
+ /* Create FT session for the re-association at this point */
+ if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
+ bss_description = mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription;
+ if((ft_session_entry = peCreateSession(mac, bss_description->bssId,
+ &session_id, mac->lim.maxStation)) == NULL) {
+ limLog(mac, LOGE,
+ FL("session can not be created for pre-auth AP"));
+ mac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
+ goto out;
+ }
+ ft_session_entry->peSessionId = session_id;
+ sirCopyMacAddr(ft_session_entry->selfMacAddr,
+ session_entry->selfMacAddr);
+ sirCopyMacAddr(ft_session_entry->limReAssocbssId,
+ bss_description->bssId);
+ ft_session_entry->bssType = session_entry->bssType;
+
+ if (ft_session_entry->bssType == eSIR_INFRASTRUCTURE_MODE)
+ ft_session_entry->limSystemRole = eLIM_STA_ROLE;
+
+ ft_session_entry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+ mac->ft.ftPEContext.pftSessionEntry = ft_session_entry;
+ limLog(mac, LOG1,"%s:created session (%p) with id = %d",
+ __func__, ft_session_entry, ft_session_entry->peSessionId);
+
+ /* Update the ReAssoc BSSID of the current session */
+ sirCopyMacAddr(session_entry->limReAssocbssId, bss_description->bssId);
+ limPrintMacAddr(mac, session_entry->limReAssocbssId, LOG1);
+
+ /* Prepare session for roamable AP */
+ lim_process_preauth_mbb_result(mac,
+ mac->ft.ftPEContext.ftPreAuthStatus, (tANI_U32 *)session_entry);
+ return;
+ }else {
+ lim_handle_preauth_mbb_fail(mac, session_entry);
+ return;
+ }
+
+out:
+ /* This sequence needs to be executed in case of failure*/
+ if (session_entry->currentOperChannel !=
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ limChangeChannelWithCallback(mac, session_entry->currentOperChannel,
+ lim_perform_post_preauth_mbb_channel_change, NULL, session_entry);
+ } else {
+ /* Link needs to be resumed as link was suspended for same channel */
+ peSetResumeChannel(mac, 0, 0);
+ limResumeLink(mac, lim_process_preauth_mbb_result,
+ (tANI_U32 *)session_entry);
+ }
+}
+
+/**
+ * lim_process_preauth_mbb_rsp_timeout() -Process preauth response timeout
+ * @mac: MAC context
+ *
+ * This function is called if preauth response is not received from the AP
+ * within timeout
+ */
+void lim_process_preauth_mbb_rsp_timeout(tpAniSirGlobal mac)
+{
+ tpPESession session_entry;
+
+ /*
+ * Pre auth is failed. Need to resume link and get back on
+ * to home channel.
+ */
+ limLog(mac, LOG1, FL("Pre-Auth MBB Time Out!!!!"));
+
+ if((session_entry = peFindSessionBySessionId(mac,
+ mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId))== NULL) {
+ limLog(mac, LOGE, FL("session does not exist for given session id"));
+ return;
+ }
+
+ /*
+ * To handle the race condition where we recieve preauth rsp after
+ * timer has expired.
+ */
+ if (mac->ft.ftPEContext.pFTPreAuthReq == NULL) {
+ limLog(mac, LOGE, FL("Auth Rsp might already be posted to SME"
+ "and cleanup done! sessionId:%d"),
+ mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId);
+ return;
+ }
+
+ if (eANI_BOOLEAN_TRUE ==
+ mac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
+ limLog(mac, LOGE,
+ FL("Auth rsp already posted to SME session %p"), session_entry);
+ return;
+ } else {
+ /*
+ * Here we are sending preauth rsp with failure state
+ * and which is forwarded to SME. Now, if we receive an preauth
+ * resp from AP with success it would create a FT pesession, but
+ * will be dropped in SME leaving behind the pesession.
+ * Mark Preauth rsp processed so that any rsp from AP is dropped in
+ * limProcessAuthFrameNoSession.
+ */
+ limLog(mac,LOG1,
+ FL("Auth rsp not yet posted to SME session %p)"), session_entry);
+ mac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed =
+ eANI_BOOLEAN_TRUE;
+ }
+ /*
+ * Ok, so attempted a Pre-Auth and failed. If we are off channel. We need
+ * to get back.
+ */
+ lim_handle_pre_auth_mbb_rsp(mac, eSIR_FAILURE, session_entry);
+ }
+
+/**
+ * lim_process_reassoc_mbb_rsp_timeout() -Process reassoc response timeout
+ * @mac: MAC context
+ *
+ * This function is called if preauth response is not received from the
+ * AP within timeout
+ */
+void lim_process_reassoc_mbb_rsp_timeout(tpAniSirGlobal mac)
+{
+ tpPESession session_entry, ft_session_entry;
+ tANI_U8 session_id;
+
+ if((ft_session_entry = peFindSessionBySessionId(mac,
+ mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId))== NULL) {
+ limLog(mac, LOGE,
+ FL("ft session does not exist for given session id %d"),
+ mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId);
+ return;
+ }
+
+ limLog(mac, LOG1, FL("Reassoc timeout happened in state %d"),
+ ft_session_entry->limMlmState);
+
+ if((session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId, &session_id))== NULL) {
+ limLog(mac, LOGE,
+ FL("session does not exist for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId));
+ return;
+ }
+
+ lim_handle_reassoc_mbb_fail(mac, ft_session_entry);
+
+}
+
+
+/**
+ * lim_perform_pre_auth_reassoc() -Sends preauth request
+ * @mac: MAC context
+ * @status: status of message
+ * @data: gives information of session
+ * @session_entry: session entry
+ *
+ * This function process preauth request received from CSR
+ */
+static inline
+void lim_perform_pre_auth_reassoc(tpAniSirGlobal mac, eHalStatus status,
+ tANI_U32 *data, tpPESession session_entry)
+{
+ tSirMacAuthFrameBody authFrame;
+
+ if (status != eHAL_STATUS_SUCCESS) {
+ limLog(mac, LOGE,
+ FL("Change channel not successful for pre-auth"));
+ goto preauth_fail;
+ }
+
+ limLog(mac, LOGE,
+ FL("session id %d"), session_entry->peSessionId);
+
+ mac->ft.ftPEContext.psavedsessionEntry = session_entry;
+
+ authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM;
+ authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+ authFrame.authStatusCode = 0;
+
+ /* Start timer here to come back to operating channel. */
+ mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId =
+ session_entry->peSessionId;
+
+ limSendAuthMgmtFrame(mac, &authFrame,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ LIM_NO_WEP_IN_FC, session_entry, eSIR_FALSE);
+
+ MTRACE(macTrace(mac, TRACE_CODE_TIMER_ACTIVATE,
+ session_entry->peSessionId, eLIM_PREAUTH_MBB_RSP_TIMER));
+
+ if(TX_SUCCESS !=
+ tx_timer_activate(&mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer)) {
+ limLog(mac, LOGE, FL("Pre Auth MBB Rsp Timer Start Failed"));
+
+ mac->ft.ftPEContext.psavedsessionEntry = NULL;
+ goto preauth_fail;
+ }
+
+ return;
+
+preauth_fail:
+ lim_handle_pre_auth_mbb_rsp(mac, eSIR_FAILURE, session_entry);
+ return;
+}
+
+/**
+ * pre_auth_mbb_suspend_link_handler() -Handler for suspend link
+ * @mac: MAC context
+ * @status: status of message
+ * @data: gives information of session
+ *
+ * This function process preauth request received from CSR
+ */
+static inline
+void pre_auth_mbb_suspend_link_handler(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession session_entry;
+
+ if (status != eHAL_STATUS_SUCCESS) {
+ limLog(mac, LOGE, FL("Link suspend failed"));
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE,
+ (tpPESession)data, SIR_MBB_CONNECTED);
+ return;
+ }
+
+ session_entry = (tpPESession)data;
+
+ if (session_entry->currentOperChannel !=
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ limChangeChannelWithCallback(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum,
+ lim_perform_pre_auth_reassoc, NULL, session_entry);
+ return;
+ } else {
+ lim_perform_pre_auth_reassoc(mac, eHAL_STATUS_SUCCESS,
+ NULL, session_entry);
+ return;
+ }
+}
+
+/**
+ * lim_process_pre_auth_reassoc_req() -Process preauth request
+ * @hal: HAL context
+ * @msg: message
+ *
+ * This function process preauth request received from CSR
+ */
+void lim_process_pre_auth_reassoc_req(tpAniSirGlobal mac, tpSirMsgQ msg)
+{
+ tpPESession session_entry;
+ tANI_U8 session_id;
+
+ limFTInit(mac);
+
+ /* Can set it only after sending auth */
+ mac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
+
+ /* We need information from the Pre-Auth Req. Lets save that */
+ mac->ft.ftPEContext.pFTPreAuthReq = (tpSirFTPreAuthReq)msg->bodyptr;
+ if (!mac->ft.ftPEContext.pFTPreAuthReq) {
+ limLog(mac, LOGE,
+ FL("pFTPreAuthReq is NULL"));
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ /* Get the current session entry */
+ session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId, &session_id);
+ if (session_entry == NULL) {
+ limLog(mac, LOGE,
+ FL("Unable to find session for the following bssid"));
+ limPrintMacAddr(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->currbssId, LOGE);
+
+ /* Post the pre auth response to SME */
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ limLog(mac, LOG1,
+ FL("set link with eSIR_LINK_PRE_AUTH_REASSOC_STATE"));
+
+ if (limSetLinkState(mac, eSIR_LINK_PRE_AUTH_REASSOC_STATE,
+ session_entry->bssId, session_entry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS) {
+ limLog(mac, LOGE,
+ FL("set link failed for eSIR_LINK_PRE_AUTH_REASSOC_STATE"));
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL,
+ SIR_MBB_CONNECTED);
+ return;
+ }
+
+ /*
+ * Suspend link for same channel or different channel so that STA
+ * can be in power save for connected AP.
+ */
+ limLog(mac, LOG1,
+ FL("pre-auth on channel %d (session %p) currentOperChannel %d"),
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum,
+ session_entry, session_entry->currentOperChannel);
+ limSuspendLink(mac, eSIR_CHECK_ROAMING_SCAN,
+ pre_auth_mbb_suspend_link_handler,
+ (tANI_U32 *)session_entry);
+}
+
+
+/**
+ * lim_process_sta_mlm_del_sta_rsp_mbb() -Process del sta response
+ * @mac: MAC context
+ * @lim_msg: lim message
+ * @session_entry: session entry
+ *
+ * This function process del sta response
+ */
+void lim_process_sta_mlm_del_sta_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ lim_msg, tpPESession session_entry)
+{
+ tpDeleteStaParams del_sta_params = (tpDeleteStaParams)lim_msg->bodyptr;
+ tpDphHashNode sta_ds = NULL;
+ tANI_U8 session_id;
+ tpPESession ft_session_entry;
+
+ if(NULL == del_sta_params) {
+ limLog(mac, LOGE, FL("Encountered NULL Pointer"));
+ goto end;
+ }
+
+ limLog(mac, LOG1, FL("Del STA RSP received. Status:%d AssocID:%d"),
+ del_sta_params->status, del_sta_params->assocId);
+
+ if (eHAL_STATUS_SUCCESS != del_sta_params->status) {
+ limLog(mac, LOGE, FL("Del STA failed! Status:%d, still proceeding"
+ "with Del BSS"), del_sta_params->status);
+ }
+
+ sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+
+ if (sta_ds == NULL) {
+ limLog( mac, LOGE, FL("DPH Entry for STA %X missing"),
+ del_sta_params->assocId);
+ goto end;
+ }
+
+ if (eLIM_MLM_WT_DEL_STA_RSP_STATE != session_entry->limMlmState) {
+ limLog(mac, LOGE,
+ FL( "Received unexpected WDA_DELETE_STA_RSP in state %s" ),
+ limMlmStateStr(session_entry->limMlmState));
+ goto end;
+ }
+
+ limLog( mac, LOG1, FL("STA AssocID %d MAC "), sta_ds->assocId);
+ limPrintMacAddr(mac, sta_ds->staAddr, LOG1);
+
+ /*
+ * we must complete all cleanup related to del sta
+ * before calling del bss.
+ */
+ if (NULL != lim_msg->bodyptr) {
+ vos_mem_free(del_sta_params);
+ lim_msg->bodyptr = NULL;
+ }
+
+ /* Proceed to do del bss even if del sta resulted in failure */
+ lim_del_bss_mbb(mac, sta_ds, 0, session_entry);
+ return;
+
+end:
+ if(NULL != lim_msg->bodyptr) {
+ vos_mem_free(del_sta_params);
+ lim_msg->bodyptr = NULL;
+ }
+
+ /* Connected AP lim cleanup.*/
+ lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+ ft_session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ &session_id);
+ if (ft_session_entry == NULL) {
+ limLog(mac, LOGE,
+ FL("Unable to find session for the following bssid"));
+ limPrintMacAddr(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+ return;
+ }
+
+ /*
+ * eHAL_STATUS_INVALID_PARAMETER is used
+ * so that full cleanup is triggered.
+ */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+ (tANI_U32 *)ft_session_entry);
+}
+
+/**
+ * lim_cleanup_rx_path_mbb() -cleans up tspec related info
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @session_entry: session entry of connected AP
+ *
+ * This function cleans up tspec related info
+ */
+void lim_cleanup_rx_path_mbb(tpAniSirGlobal mac,
+ tpDphHashNode sta_ds,tpPESession session_entry)
+{
+ limLog(mac, LOG1, FL("AID %d limSmeState %d, mlmState %d"),
+ sta_ds->assocId, session_entry->limSmeState,
+ sta_ds->mlmStaContext.mlmState);
+
+ session_entry->isCiscoVendorAP = FALSE;
+
+ if (mac->lim.gLimAddtsSent)
+ tx_timer_deactivate(&mac->lim.limTimers.gLimAddtsRspTimer);
+
+ /* delete all tspecs associated with this sta. */
+ limAdmitControlDeleteSta(mac, sta_ds->assocId);
+}
+
+
+/**
+ * lim_cleanup_connected_ap() -cleans up connected AP lim info
+ * @mac: MAC context
+ * @sta_ds: station entry
+ * @session_entry: session entry of connected AP
+ *
+ * This function cleans up connected AP lim info
+ */
+void lim_cleanup_connected_ap(tpAniSirGlobal mac, tpDphHashNode sta_ds,
+ tpPESession session_entry)
+{
+ lim_cleanup_rx_path_mbb(mac, sta_ds, session_entry);
+ limDeleteDphHashEntry(mac, sta_ds->staAddr,
+ sta_ds->assocId, session_entry);
+
+ /**
+ * Make STA hash entry invalid at eCPU so that DPH
+ * does not process any more data packets and
+ * releases those BDs
+ */
+ sta_ds->valid = 0;
+
+ peDeleteSession(mac, session_entry);
+}
+
+/**
+ * lim_process_sta_mlm_del_bss_rsp_mbb() -Process del bss response of
+ * connected AP
+ * @mac: MAC context
+ * @lim_msg: lim message
+ * @session_entry: session entry of connected AP
+ *
+ * This function process del sta response
+ */
+void lim_process_sta_mlm_del_bss_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ lim_msg, tpPESession session_entry)
+{
+ tpDeleteBssParams delbss_params = (tpDeleteBssParams)lim_msg->bodyptr;
+ tpDphHashNode sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ tpPESession ft_session_entry;
+ tANI_U8 session_id;
+
+ if (NULL == delbss_params) {
+ limLog(mac, LOGE, FL( "Invalid body pointer in message"));
+ goto end;
+ }
+
+ ft_session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ &session_id);
+ if (ft_session_entry == NULL) {
+ limLog(mac, LOGE,
+ FL("Unable to find session for the following bssid"));
+ limPrintMacAddr(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+ goto end;
+ }
+
+ if(eHAL_STATUS_SUCCESS == delbss_params->status) {
+ limLog(mac, LOG1,
+ FL( "STA received the DEL_BSS_RSP for BSSID: %X."),
+ delbss_params->bssIdx);
+
+ if(sta_ds == NULL) {
+ limLog(mac, LOGE, FL("DPH Entry for STA missing"));
+ goto end;
+ }
+ if(eLIM_MLM_WT_DEL_BSS_RSP_STATE != session_entry->limMlmState) {
+ limLog(mac, LOGE,
+ FL("Received unexpected WDA_DEL_BSS_RSP in state %d"),
+ session_entry->limMlmState);
+ goto end;
+ }
+ limLog(mac, LOG1, FL("STA AssocID %d MAC "), sta_ds->assocId );
+ limPrintMacAddr(mac, sta_ds->staAddr, LOG1);
+
+ lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+ lim_add_bss_mbb(mac, sta_ds, ft_session_entry);
+
+ if(NULL != lim_msg->bodyptr) {
+ vos_mem_free(delbss_params);
+ lim_msg->bodyptr = NULL;
+ }
+ return;
+ } else {
+ /*
+ * If del bss response is failure, cleanup sessions of both currently
+ * connected AP and roamable AP as add bss can not be send
+ * without successful delbss.
+ */
+ limLog(mac, LOGE,
+ FL("DEL BSS failed! Status:%d"), delbss_params->status);
+
+ if(NULL != lim_msg->bodyptr) {
+ vos_mem_free(delbss_params);
+ lim_msg->bodyptr = NULL;
+ }
+
+ /* Connected AP lim cleanup.*/
+ lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+ /* Newly created session cleanup */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_DEL_BSS_FAIL,
+ (tANI_U32 *)ft_session_entry);
+ return;
+ }
+
+end:
+ if(NULL != lim_msg->bodyptr) {
+ vos_mem_free(delbss_params);
+ lim_msg->bodyptr = NULL;
+ }
+
+ lim_cleanup_connected_ap(mac, sta_ds, session_entry);
+
+ ft_session_entry = peFindSessionByBssid(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ &session_id);
+ if (ft_session_entry == NULL) {
+ limLog(mac, LOGE,
+ FL("Unable to find session for the following bssid"));
+ limPrintMacAddr(mac,
+ mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+ return;
+ }
+
+ /*
+ * eHAL_STATUS_INVALID_PARAMETER is used
+ * so that full cleanup is triggered.
+ */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER,
+ (tANI_U32 *)ft_session_entry);
+}
+
+
+void lim_fill_add_sta_params_mbb(tpAniSirGlobal mac,
+ tpPESession session_entry, tpAddStaParams add_sta_params)
+{
+ tANI_U32 listen_interval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+ tANI_U32 self_sta_dot11_mode = 0;
+
+ vos_mem_copy(add_sta_params->staMac, session_entry->selfMacAddr,
+ sizeof(tSirMacAddr));
+ vos_mem_copy(add_sta_params->bssId, session_entry->bssId,
+ sizeof(tSirMacAddr));
+
+ add_sta_params->staType = STA_ENTRY_SELF;
+ add_sta_params->status = eHAL_STATUS_SUCCESS;
+ add_sta_params->respReqd = 1;
+
+ add_sta_params->sessionId = session_entry->peSessionId;
+ add_sta_params->staIdx = HAL_STA_INVALID_IDX;
+ add_sta_params->updateSta = FALSE;
+
+ add_sta_params->shortPreambleSupported =
+ session_entry->beaconParams.fShortPreamble;
+
+#ifdef WLAN_FEATURE_11AC
+ limPopulatePeerRateSet(mac, &add_sta_params->supportedRates, NULL,
+ false,session_entry, NULL);
+#else
+ limPopulatePeerRateSet(mac, &add_sta_params->supportedRates, NULL,
+ false,session_entry);
+#endif
+
+ if(session_entry->htCapability) {
+ add_sta_params->htCapable = session_entry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+ add_sta_params->vhtCapable = session_entry->vhtCapability;
+ add_sta_params->vhtTxChannelWidthSet = session_entry->vhtTxChannelWidthSet;
+#endif
+
+#ifdef DISABLE_GF_FOR_INTEROP
+ if((session_entry->pLimJoinReq != NULL) &&
+ (!session_entry->pLimJoinReq->bssDescription.aniIndicator)) {
+ limLog(mac, LOGE,
+ FL("Turning off Greenfield, when adding self entry"));
+ add_sta_params->greenFieldCapable =
+ WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
+ }
+ else
+#endif
+ add_sta_params->greenFieldCapable =
+ limGetHTCapability( mac, eHT_GREENFIELD, session_entry);
+
+ if (session_entry->limRFBand == SIR_BAND_2_4_GHZ)
+ add_sta_params->txChannelWidthSet =
+ mac->roam.configParam.channelBondingMode24GHz;
+ else
+ add_sta_params->txChannelWidthSet =
+ mac->roam.configParam.channelBondingMode5GHz;
+
+ add_sta_params->mimoPS =
+ limGetHTCapability(mac, eHT_MIMO_POWER_SAVE, session_entry);
+ add_sta_params->rifsMode =
+ limGetHTCapability(mac, eHT_RIFS_MODE, session_entry);
+ add_sta_params->lsigTxopProtection =
+ limGetHTCapability(mac, eHT_LSIG_TXOP_PROTECTION, session_entry);
+ add_sta_params->delBASupport =
+ limGetHTCapability(mac, eHT_DELAYED_BA, session_entry);
+ add_sta_params->maxAmpduDensity =
+ limGetHTCapability(mac, eHT_MPDU_DENSITY, session_entry);
+ add_sta_params->maxAmpduSize =
+ limGetHTCapability(mac, eHT_MAX_RX_AMPDU_FACTOR, session_entry);
+ add_sta_params->maxAmsduSize =
+ limGetHTCapability(mac, eHT_MAX_AMSDU_LENGTH, session_entry);
+ add_sta_params->fDsssCckMode40Mhz =
+ limGetHTCapability(mac, eHT_DSSS_CCK_MODE_40MHZ, session_entry);
+ add_sta_params->fShortGI20Mhz =
+ limGetHTCapability(mac, eHT_SHORT_GI_20MHZ, session_entry);
+ add_sta_params->fShortGI40Mhz =
+ limGetHTCapability(mac, eHT_SHORT_GI_40MHZ, session_entry);
+ }
+
+ if (wlan_cfgGetInt(mac, WNI_CFG_LISTEN_INTERVAL,
+ &listen_interval) != eSIR_SUCCESS)
+ limLog(mac, LOGE, FL("Couldn't get LISTEN_INTERVAL"));
+
+ add_sta_params->listenInterval = (tANI_U16)listen_interval;
+
+ wlan_cfgGetInt(mac, WNI_CFG_DOT11_MODE, &self_sta_dot11_mode);
+ add_sta_params->supportedRates.opRateMode =
+ limGetStaRateMode((tANI_U8)self_sta_dot11_mode);
+
+ mac->ft.ftPEContext.pAddStaReq = add_sta_params;
+
+
+}
+
+void lim_process_sta_mlm_add_bss_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ limMsgQ,tpPESession session_entry)
+{
+ tpAddBssParams add_bss_params = (tpAddBssParams)limMsgQ->bodyptr;
+ tpAddStaParams add_sta_params = NULL;
+ tpDphHashNode sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+
+ if(add_bss_params == 0)
+ goto end;
+
+ limLog(mac, LOG1, FL("Add BSS RSP received. Status:%d"),
+ add_bss_params->status);
+
+ if(eHAL_STATUS_SUCCESS == add_bss_params->status) {
+
+ if(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE != session_entry->limMlmState) {
+ limLog(mac, LOGE,
+ FL("Received unexpected ADD BSS in state %d"),
+ session_entry->limMlmState);
+ goto end;
+ }
+
+ session_entry->bssIdx = add_bss_params->bssIdx;
+
+ sta_ds->bssId = add_bss_params->bssIdx;
+ sta_ds->staIndex = add_bss_params->staContext.staIdx;
+ sta_ds->ucUcastSig = add_bss_params->staContext.ucUcastSig;
+ sta_ds->ucBcastSig = add_bss_params->staContext.ucBcastSig;
+
+ rrmCacheMgmtTxPower(mac, add_bss_params->txMgmtPower, session_entry);
+
+ /* Allocate memory for add sta params */
+ add_sta_params = vos_mem_malloc(sizeof( tAddStaParams ));
+ if (NULL == add_sta_params) {
+ limLog(mac, LOGE,
+ FL("Unable to allocate memory during ADD_STA"));
+ goto end;
+ }
+ vos_mem_set(add_sta_params, sizeof(tAddStaParams), 0);
+
+ /* Prepare add sta params */
+ lim_fill_add_sta_params_mbb(mac, session_entry, add_sta_params);
+
+ if(0 != limMsgQ->bodyptr) {
+ vos_mem_free(add_bss_params);
+ add_bss_params = NULL;
+ limMsgQ->bodyptr = NULL;
+ }
+
+ lim_add_sta_mbb(mac, session_entry->limAID, session_entry);
+
+ } else {
+ /*
+ * If add bss response is failure, cleanup session of roamable AP
+ * as cleanup of connected bss happened during del bss
+ */
+ limLog(mac, LOGE,
+ FL("ADD BSS failed! Status:%d"), add_bss_params->status);
+
+ /* Newly created session cleanup */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_ADD_BSS_FAIL,
+ (tANI_U32 *)session_entry);
+ }
+
+end:
+ if(0 != limMsgQ->bodyptr) {
+ vos_mem_free(add_bss_params);
+ add_bss_params = NULL;
+ limMsgQ->bodyptr = NULL;
+ }
+}
+
+/*
+ * lim_perform_post_add_sta_rsp() -invokes resume callback to handle add sta response
+ * @mac: MAC context
+ * @status: status
+ * @data: pointer to data
+ *
+ * This function invokes resume callback
+ */
+void lim_perform_post_add_sta_rsp(tpAniSirGlobal mac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpDphHashNode sta_ds;
+ /* session entry for newly roamed ap */
+ tpPESession session_entry;
+
+ session_entry = (tpPESession)data;
+
+ limLog(mac, LOG1, FL("forwarding cached packets"));
+ WLANTL_PreAssocForward(true);
+
+ sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if(NULL != sta_ds)
+ sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ else {
+ limLog(mac, LOGE,
+ FL("Unable to get the DPH Hash Entry for AID - %d"),
+ DPH_STA_HASH_INDEX_PEER);
+ return;
+ }
+
+ session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE));
+
+#ifdef FEATURE_WLAN_TDLS
+ /* initialize TDLS peer related data */
+ limInitTdlsData(mac, session_entry);
+#endif
+
+ if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE, session_entry->bssId,
+ session_entry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) {
+ limLog(mac, LOGE, FL("Set link state to POSTASSOC failed"));
+ return;
+ }
+
+ session_entry->limSmeState = eLIM_SME_LINK_EST_STATE;
+
+ lim_post_pre_auth_reassoc_rsp(mac, eSIR_SUCCESS, session_entry,
+ SIR_MBB_CONNECTED);
+
+ /* Freeup the cached preauth request */
+ if (mac->ft.ftPEContext.pFTPreAuthReq) {
+ limLog(mac, LOG1, FL("Freeing pFTPreAuthReq= %p"),
+ mac->ft.ftPEContext.pFTPreAuthReq);
+ if (mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription) {
+ vos_mem_free(mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription);
+ mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription = NULL;
+ }
+ vos_mem_free(mac->ft.ftPEContext.pFTPreAuthReq);
+ mac->ft.ftPEContext.pFTPreAuthReq = NULL;
+ }
+}
+
+void lim_process_sta_mlm_add_sta_rsp_mbb(tpAniSirGlobal mac,
+ tpSirMsgQ limMsgQ,tpPESession session_entry)
+{
+ tpAddStaParams add_sta_params = (tpAddStaParams)limMsgQ->bodyptr;
+
+ if(NULL == add_sta_params) {
+ limLog(mac, LOGE, FL("Encountered NULL Pointer"));
+ return;
+ }
+
+ limLog(mac, LOG1, FL("Add STA RSP received. Status:%d"),
+ add_sta_params->status);
+
+ if (eHAL_STATUS_SUCCESS == add_sta_params->status) {
+ if ( eLIM_MLM_WT_ADD_STA_RSP_STATE != session_entry->limMlmState) {
+ limLog(mac, LOGE,
+ FL("Received unexpected ADD_STA_RSP in state %d"),
+ session_entry->limMlmState);
+ goto end;
+ }
+
+ /*
+ * 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;
+
+ limLog(mac, LOG1, FL("resuming to oper ch %d"),
+ session_entry->currentOperChannel);
+
+ peSetResumeChannel(mac, session_entry->currentOperChannel, 0);
+ limResumeLink(mac, lim_perform_post_add_sta_rsp, (tANI_U32 *)session_entry);
+ } else {
+ limLog(mac, LOGE, FL( "ADD_STA failed!"));
+
+ /* Newly created session cleanup */
+ lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_ADD_BSS_FAIL,
+ (tANI_U32 *)session_entry);
+
+ }
+end:
+ if( 0 != limMsgQ->bodyptr )
+ {
+ vos_mem_free(add_sta_params);
+ limMsgQ->bodyptr = NULL;
+ }
+}
+
+eAniBoolean lim_is_mbb_reassoc_in_progress(tpAniSirGlobal mac,
+ tpPESession session_entry)
+{
+ if (session_entry == NULL)
+ return eANI_BOOLEAN_FALSE;
+
+ if ((eLIM_STA_ROLE == session_entry->limSystemRole) &&
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb) {
+ limLog(mac, LOG1, FL("MBB Reassoc in progress"));
+ return eANI_BOOLEAN_TRUE;
+ }
+
+ return eANI_BOOLEAN_FALSE;
+}
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index e92ff99..7e88126 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1199,6 +1199,11 @@
v_U32_t PERtimerThreshold;
v_U32_t PERroamTriggerPercent;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
#endif
tANI_BOOLEAN ignorePeerErpInfo;
@@ -1766,6 +1771,5 @@
---------------------------------------------------------------------------*/
eCsrBand csrGetCurrentBand (tHalHandle hHal);
-
#endif
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index a780af6..09a507b 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -206,7 +206,7 @@
eCsrLostLink1Abort,
eCsrLostLink2Abort,
eCsrLostLink3Abort,
-
+ ecsr_mbb_perform_preauth_reassoc,
}eCsrRoamReason;
typedef enum
@@ -636,6 +636,10 @@
#endif
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ tANI_BOOLEAN enable_lfr_mbb;
+#endif
+
#ifdef FEATURE_WLAN_ESE
tANI_U8 isEseIniFeatureEnabled;
#endif
@@ -1494,3 +1498,18 @@
eHalStatus csrEnableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId);
eHalStatus csrDisableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId);
#endif /* WLAN_FEATURE_RMC */
+
+eHalStatus csrRoamStopNetwork(tpAniSirGlobal pMac, tANI_U32 sessionId,
+ tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc,
+ tDot11fBeaconIEs *pIes);
+
+eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac,
+ tANI_U32 sessionId, eCsrAuthType authType,
+ tSirBssDescription *pSirBssDesc,
+ tDot11fBeaconIEs *pIes);
+
+void csrRoamSubstateChange(tpAniSirGlobal pMac,
+ eCsrRoamSubState NewSubstate, tANI_U32 sessionId);
+
+eHalStatus csrRoamFreeConnectedInfo(tpAniSirGlobal pMac,
+ tCsrRoamConnectedInfo *pConnectedInfo);
diff --git a/CORE/SME/inc/csrNeighborRoam.h b/CORE/SME/inc/csrNeighborRoam.h
index 5df4eee..8bd7102 100644
--- a/CORE/SME/inc/csrNeighborRoam.h
+++ b/CORE/SME/inc/csrNeighborRoam.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -41,6 +41,12 @@
#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
#include "sme_Api.h"
+/* 15 seconds, for WPA, WPA2, CCKM */
+#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD (15 * PAL_TIMER_TO_SEC_UNIT)
+/* 120 seconds, for WPS */
+#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * PAL_TIMER_TO_SEC_UNIT)
+
+
/* Enumeration of various states in neighbor roam algorithm */
typedef enum
{
@@ -55,6 +61,10 @@
eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING,
eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE,
#endif /* WLAN_FEATURE_VOWIFI_11R */
+#ifdef WLAN_FEATURE_LFR_MBB
+ eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC,
+#endif
+
eNEIGHBOR_STATE_MAX
} eCsrNeighborRoamState;
@@ -206,6 +216,11 @@
vos_timer_t forcedInitialRoamTo5GHTimer;
tANI_U8 isForcedInitialRoamTo5GH;
tANI_U8 lastSentCmd;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ bool is_pre_auth_reassoc_mbb_timer_started;
+#endif
+
} tCsrNeighborRoamControlInfo, *tpCsrNeighborRoamControlInfo;
@@ -251,6 +266,15 @@
tANI_U8 *pOutputChannelList,
tANI_U8 outputNumOfChannels,
tANI_U8 *pMergedOutputNumOfChannels);
+tANI_BOOLEAN
+csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac,
+ tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry);
+eHalStatus
+csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac,
+ tSirMacAddr bssId);
+void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac,
+ tpCsrNeighborRoamBSSInfo neighborRoamBSSNode);
+
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
#define ROAM_SCAN_OFFLOAD_START 1
@@ -282,6 +306,10 @@
eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac);
eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, eHalStatus status);
eHalStatus csrNeighborRoamStartLfrScan(tpAniSirGlobal pMac, tANI_U8 OffloadCmdStopReason);
+eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac,
+ tANI_U32 interval);
+void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid);
+
#endif
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
diff --git a/CORE/SME/inc/csr_roam_mbb.h b/CORE/SME/inc/csr_roam_mbb.h
new file mode 100644
index 0000000..aa0bcbc
--- /dev/null
+++ b/CORE/SME/inc/csr_roam_mbb.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+eHalStatus csr_neighbor_roam_issue_preauth_reassoc(tpAniSirGlobal mac);
+
+eHalStatus csr_roam_issue_preauth_reassoc_req(tHalHandle hal,
+ tANI_U32 session_id, tpSirBssDescription bss_description);
+
+void csr_roam_preauth_rsp_mbb_processor(tHalHandle hal,
+ tpSirFTPreAuthRsp pre_auth_rsp);
+
+void csr_preauth_reassoc_mbb_timer_callback(void *context);
+
+void csr_stop_preauth_reassoc_mbb_timer(tpAniSirGlobal mac);
+
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index ca101f7..79f27af 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -189,7 +189,10 @@
void (*pOemDataIndCb) (void *, const tANI_U16, void *, tANI_U32);
void *pOemDataCallbackContext;
#endif /* FEATURE_OEM_DATA_SUPPORT */
-
+#ifdef WLAN_FEATURE_LFR_MBB
+ void (*roaming_mbb_callback)(void* mac, tANI_U32 session_id,
+ void* bss_description, void *reassoc_req, tANI_U32 csr_roam_op_code);
+#endif
} tSmeStruct, *tpSmeStruct;
diff --git a/CORE/SME/inc/sme_FTApi.h b/CORE/SME/inc/sme_FTApi.h
index 4eed9f5..0a57aa5 100644
--- a/CORE/SME/inc/sme_FTApi.h
+++ b/CORE/SME/inc/sme_FTApi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -72,6 +72,12 @@
tCsrRoamSetKey *pCsrFTKeyInfo;
v_BOOL_t addMDIE;
+
+ tANI_BOOLEAN is_preauth_lfr_mbb;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ vos_timer_t pre_auth_reassoc_mbb_timer;
+#endif
} tftSMEContext, *tpftSMEContext;
/*--------------------------------------------------------------------------
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 4c6aa21..893eda0 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -76,14 +76,16 @@
#include "csrEse.h"
#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */
#include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
+
+
#define CSR_NUM_IBSS_START_CHANNELS_50 4
#define CSR_NUM_IBSS_START_CHANNELS_24 3
#define CSR_DEF_IBSS_START_CHANNEL_50 36
#define CSR_DEF_IBSS_START_CHANNEL_24 1
-/* 15 seconds, for WPA, WPA2, CCKM */
-#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD (15 * PAL_TIMER_TO_SEC_UNIT)
-/* 120 seconds, for WPS */
-#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * PAL_TIMER_TO_SEC_UNIT)
+
/*---------------------------------------------------------------------------
OBIWAN recommends [8 10]% : pick 9%
---------------------------------------------------------------------------*/
@@ -214,12 +216,10 @@
static eHalStatus csrRoamStartRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval);
static eHalStatus csrRoamStopRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId);
static void csrRoamRoamingTimerHandler(void *pv);
-eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac, tANI_U32 interval);
eHalStatus csrRoamStopWaitForKeyTimer(tpAniSirGlobal pMac);
static void csrRoamWaitForKeyTimeOutHandler(void *pv);
static eHalStatus CsrInit11dInfo(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
static eHalStatus csrInitChannelPowerList( tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
-static eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo );
eHalStatus csrSendMBSetContextReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId,
tSirMacAddr peerMacAddr, tANI_U8 numKeys, tAniEdType edType,
tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection,
@@ -230,7 +230,6 @@
tCsrRoamProfile *pProfile );
void csrRoamStatisticsTimerHandler(void *pv);
void csrRoamStatsGlobalClassDTimerHandler(void *pv);
-static void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid);
VOS_STATUS csrRoamVccTriggerRssiIndCallback(tHalHandle hHal,
v_U8_t rssiNotification,
void * context);
@@ -1007,7 +1006,7 @@
return (status);
}
-static eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo )
+eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo )
{
eHalStatus status = eHAL_STATUS_SUCCESS;
if( pConnectedInfo->pbFrames )
@@ -1976,6 +1975,11 @@
pParam->PERMinRssiThresholdForRoam;
pMac->PERroamTimeout = pParam->waitPeriodForNextPERScan;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ pMac->roam.configParam.enable_lfr_mbb = pParam->enable_lfr_mbb;
+#endif
+
#ifdef FEATURE_WLAN_LFR
pMac->roam.configParam.isFastRoamIniFeatureEnabled = pParam->isFastRoamIniFeatureEnabled;
pMac->roam.configParam.MAWCEnabled = pParam->MAWCEnabled;
@@ -2206,6 +2210,11 @@
pParam->PERMinRssiThresholdForRoam =
pMac->roam.configParam.PERMinRssiThresholdForRoam;
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ pParam->enable_lfr_mbb = pMac->roam.configParam.enable_lfr_mbb;
+#endif
+
#ifdef FEATURE_WLAN_LFR
pParam->isFastRoamIniFeatureEnabled = pMac->roam.configParam.isFastRoamIniFeatureEnabled;
#endif
@@ -5064,6 +5073,20 @@
pCommand->u.roamCmd.pLastRoamBss);
break;
+#ifdef WLAN_FEATURE_LFR_MBB
+ case ecsr_mbb_perform_preauth_reassoc:
+ smsLog(pMac, LOG1, FL("Attempting MBB PreAuth/Reassoc Req"));
+ status = csr_roam_issue_preauth_reassoc_req(pMac, sessionId,
+ pCommand->u.roamCmd.pLastRoamBss);
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+ smsLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+ }
+ break;
+#endif
+
default:
csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId );
@@ -5201,9 +5224,10 @@
#endif /* FEATURE_WLAN_WAPI */
extern tANI_U8 csrWpaOui[][ CSR_WPA_OUI_SIZE ];
-static eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrAuthType authType,
- tSirBssDescription *pSirBssDesc,
- tDot11fBeaconIEs *pIes)
+eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac,
+ tANI_U32 sessionId, eCsrAuthType authType,
+ tSirBssDescription *pSirBssDesc,
+ tDot11fBeaconIEs *pIes)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
@@ -7391,6 +7415,9 @@
csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
}
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
}
if( fDisassoc )
@@ -10050,6 +10077,10 @@
csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
}
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
+
pSession = CSR_GET_SESSION( pMac, sessionId );
if (!pSession)
@@ -10126,6 +10157,9 @@
csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac);
}
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
pSession = CSR_GET_SESSION( pMac, sessionId );
if(!pSession)
@@ -10918,6 +10952,13 @@
csrRoamFTPreAuthRspProcessor( pMac, (tpSirFTPreAuthRsp)pSirMsg );
break;
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP:
+ csr_roam_preauth_rsp_mbb_processor(pMac,
+ (tpSirFTPreAuthRsp)pSirMsg);
+ break;
+#endif
+
case eWNI_SME_MAX_ASSOC_EXCEEDED:
pSmeMaxAssocInd = (tSmeMaxAssocInd*)pSirMsg;
smsLog( pMac, LOG1, FL("send indication that max assoc have been reached and the new peer cannot be accepted"));
@@ -14008,6 +14049,719 @@
return( status );
}
+#ifdef WLAN_FEATURE_LFR_MBB
+/**
+ * csr_prepare_reassoc_req () - Prepares reassoc request
+ * @mac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @ies: pointer to beacon IE's
+ * @reassoc_req: pointer to reassociation request
+ *
+ *Return: None
+ */
+eHalStatus csr_fill_reassoc_req(tpAniSirGlobal mac, tANI_U32 session_id,
+ tSirBssDescription *bss_description, tDot11fBeaconIEs *ies,
+ tSirSmeJoinReq **reassoc_req)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tSirSmeJoinReq *csr_join_req;
+ tANI_U8 *buf;
+ v_U8_t acm_mask = 0, uapsd_mask;
+ tANI_U16 msg_len, w_tmp, ie_len;
+ tSirMacRateSet op_rate_set;
+ tSirMacRateSet ex_rate_set;
+ tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id);
+ tANI_U32 dw_tmp;
+ tANI_U8 wpa_rsn_ie[DOT11F_IE_RSN_MAX_LEN];
+ tANI_U32 uc_dot11_mode = 0;
+ tANI_U8 tx_bf_csn_value = 0;
+ tANI_U16 rate_bitmap = 0;
+ tANI_U16 message_type = eWNI_SME_REASSOC_REQ;
+ tCsrRoamProfile *profile;
+
+ if(!session) {
+ smsLog(mac, LOGE, FL(" session %d not found "), session_id);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ if (NULL == bss_description) {
+ smsLog(mac, LOGE, FL(" pBssDescription is NULL"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ smsLog(mac, LOG1,
+ FL("session_id %d"), session_id);
+
+ profile = vos_mem_malloc(sizeof(*profile));
+ if (NULL == profile) {
+ smsLog(mac, LOGE, FL("Memory allocation failure for profile"));
+ return eHAL_STATUS_RESOURCES;
+ }
+
+ status = csrRoamCopyProfile(mac, profile, session->pCurRoamProfile);
+ if(!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE, FL("Profile copy failed"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ do {
+ /*
+ * There are a number of variable length fields to consider.
+ * First, the tSirSmeJoinReq includes a single bssDescription.
+ * bssDescription includes a single tANI_U32 for the IE fields,
+ * but the length field in the bssDescription needs to be
+ * interpreted to determine length of the IE fields.
+ * So, take the size of the JoinReq, subtract the size of the
+ * bssDescription and add in the length from the bssDescription
+ * (then add the size of the 'length' field itself because that is
+ * NOT included in the length field). msgLen =
+ * sizeof( tSirSmeJoinReq ) - sizeof( *pBssDescription ) +
+ * pBssDescription->length + sizeof( pBssDescription->length ) +
+ * sizeof( tCsrWpaIe ) + sizeof( tCsrWpaAuthIe ) + sizeof( tANI_U16 );
+ * add in the size of the WPA IE that we may build.
+ */
+
+ msg_len = sizeof(tSirSmeJoinReq) - sizeof(*bss_description) +
+ bss_description->length + sizeof(bss_description->length) +
+ sizeof(tCsrWpaIe) + sizeof(tCsrWpaAuthIe) + sizeof(tANI_U16);
+
+ csr_join_req = vos_mem_malloc(msg_len);
+ if (NULL == csr_join_req)
+ status = eHAL_STATUS_FAILURE;
+ else
+ status = eHAL_STATUS_SUCCESS;
+ if (!HAL_STATUS_SUCCESS(status)) break;
+
+ vos_mem_set(csr_join_req, msg_len, 0);
+ *reassoc_req = csr_join_req;
+
+ csr_join_req->messageType = pal_cpu_to_be16(eWNI_SME_REASSOC_REQ);
+ csr_join_req->length = pal_cpu_to_be16(msg_len);
+ buf = &csr_join_req->sessionId;
+
+ /* session_id */
+ *buf = (tANI_U8)session_id;
+ buf++;
+
+ /* transactionId */
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += sizeof(tANI_U16);
+
+ /* ssId */
+ if(ies->SSID.present && ies->SSID.num_ssid)
+ {
+ /* ssId len */
+ *buf = ies->SSID.num_ssid;
+ buf++;
+ vos_mem_copy(buf, ies->SSID.ssid, ies->SSID.num_ssid);
+ buf += ies->SSID.num_ssid;
+ }
+ else
+ {
+ *buf = 0;
+ buf++;
+ }
+
+ /* selfMacAddr */
+ vos_mem_copy((tSirMacAddr *)buf, &session->selfMacAddr,
+ sizeof(tSirMacAddr));
+ buf += sizeof(tSirMacAddr);
+
+ /* bsstype */
+ dw_tmp =
+ pal_cpu_to_be32(csrTranslateBsstypeToMacType(profile->BSSType));
+ /* Override BssType for BTAMP */
+ if (dw_tmp == eSIR_BTAMP_STA_MODE) dw_tmp = eSIR_BTAMP_AP_MODE;
+ vos_mem_copy(buf, &dw_tmp, sizeof(tSirBssType));
+ buf += sizeof(tSirBssType);
+
+ /* dot11mode */
+ uc_dot11_mode =
+ csrTranslateToWNICfgDot11Mode(mac, session->bssParams.uCfgDot11Mode);
+ if (bss_description->channelId <= 14 &&
+ FALSE == mac->roam.configParam.enableVhtFor24GHz &&
+ WNI_CFG_DOT11_MODE_11AC == uc_dot11_mode)
+ {
+ /* Need to disable VHT operation in 2.4 GHz band */
+ uc_dot11_mode = WNI_CFG_DOT11_MODE_11N;
+ }
+ *buf = (tANI_U8)uc_dot11_mode;
+ buf++;
+
+ /* Persona */
+ *buf = (tANI_U8)profile->csrPersona;
+ buf++;
+ *buf = (tANI_U8)profile->bOSENAssociation;
+ buf++;
+ *buf = (tANI_U8)profile->bWPSAssociation;
+ buf++;
+
+ /* CBMode */
+ *buf = (tANI_U8)session->bssParams.cbMode;
+ buf++;
+
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("CSR PERSONA=%d CSR CbMode %d"), profile->csrPersona,
+ session->bssParams.cbMode);
+
+ /* uapsdPerAcBitmask */
+ *buf = profile->uapsd_mask;
+ buf++;
+
+
+ status = csrGetRateSet(mac, profile, (eCsrPhyMode)profile->phyMode,
+ bss_description, ies, &op_rate_set, &ex_rate_set,&rate_bitmap);
+ if (HAL_STATUS_SUCCESS(status))
+ {
+ /* OperationalRateSet */
+ if (op_rate_set.numRates) {
+ *buf++ = op_rate_set.numRates;
+ vos_mem_copy(buf, op_rate_set.rate, op_rate_set.numRates);
+ buf += op_rate_set.numRates;
+ } else *buf++ = 0;
+
+ /* ExtendedRateSet */
+ if (ex_rate_set.numRates) {
+ *buf++ = ex_rate_set.numRates;
+ vos_mem_copy(buf, ex_rate_set.rate, ex_rate_set.numRates);
+ buf += ex_rate_set.numRates;
+ } else *buf++ = 0;
+ }
+ else
+ {
+ *buf++ = 0;
+ *buf++ = 0;
+ }
+
+ /* rateBitmap */
+ vos_mem_copy(buf, &rate_bitmap, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+
+ profile->negotiatedAuthType =
+ mac->roam.roamSession[session_id].connectedProfile.AuthType;
+ profile->negotiatedUCEncryptionType =
+ mac->roam.roamSession[session_id].connectedProfile.EncryptionType;
+
+ /* rsnIE */
+ if ( csrIsProfileWpa(profile))
+ {
+ /* Insert the Wpa IE into the join request */
+ ie_len = csrRetrieveWpaIe(mac, profile, bss_description, ies,
+ (tCsrWpaIe *)(wpa_rsn_ie));
+ }
+ else if( csrIsProfileRSN(profile))
+ {
+ /* Insert the RSN IE into the join request */
+ ie_len = csrRetrieveRsnIe(mac, session_id, profile, bss_description,
+ ies, (tCsrRSNIe *)(wpa_rsn_ie));
+ }
+#ifdef FEATURE_WLAN_WAPI
+ else if( csrIsProfileWapi(profile))
+ {
+ /* Insert the WAPI IE into the join request */
+ ie_len = csrRetrieveWapiIe(mac, session_id, profile,
+ bss_description, ies, (tCsrWapiIe *)(wpa_rsn_ie));
+ }
+#endif
+ else
+ {
+ ie_len = 0;
+ }
+ /* remember the IE for future use */
+ if(ie_len)
+ {
+ if(ie_len > DOT11F_IE_RSN_MAX_LEN)
+ {
+ smsLog(mac, LOGE,
+ FL("WPA RSN IE length :%d is more than RSN_MAX_LEN %d"),
+ ie_len, DOT11F_IE_RSN_MAX_LEN);
+ ie_len = DOT11F_IE_RSN_MAX_LEN;
+ }
+#ifdef FEATURE_WLAN_WAPI
+ if( csrIsProfileWapi(profile))
+ {
+ /* Check whether we need to allocate more memory */
+ if(ie_len > session->nWapiReqIeLength)
+ {
+ if(session->pWapiReqIE && session->nWapiReqIeLength)
+ {
+ vos_mem_free(session->pWapiReqIE);
+ }
+ session->pWapiReqIE = vos_mem_malloc(ie_len);
+ if (NULL == session->pWapiReqIE)
+ status = eHAL_STATUS_FAILURE;
+ else
+ status = eHAL_STATUS_SUCCESS;
+ if(!HAL_STATUS_SUCCESS(status)) break;
+ }
+ session->nWapiReqIeLength = ie_len;
+ vos_mem_copy(session->pWapiReqIE, wpa_rsn_ie, ie_len);
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+ buf += ie_len;
+ }
+ else /* should be WPA/WPA2 otherwise */
+#endif
+ {
+ /* Check whether we need to allocate more memory */
+ if(ie_len > session->nWpaRsnReqIeLength)
+ {
+ if(session->pWpaRsnReqIE && session->nWpaRsnReqIeLength)
+ {
+ vos_mem_free(session->pWpaRsnReqIE);
+ }
+ session->pWpaRsnReqIE = vos_mem_malloc(ie_len);
+ if (NULL == session->pWpaRsnReqIE)
+ status = eHAL_STATUS_FAILURE;
+ else
+ status = eHAL_STATUS_SUCCESS;
+ if(!HAL_STATUS_SUCCESS(status)) break;
+ }
+ session->nWpaRsnReqIeLength = ie_len;
+ vos_mem_copy(session->pWpaRsnReqIE, wpa_rsn_ie, ie_len);
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+ buf += ie_len;
+ }
+ }
+ else
+ {
+ /* free whatever old info */
+ session->nWpaRsnReqIeLength = 0;
+ if(session->pWpaRsnReqIE)
+ {
+ vos_mem_free(session->pWpaRsnReqIE);
+ session->pWpaRsnReqIE = NULL;
+ }
+#ifdef FEATURE_WLAN_WAPI
+ session->nWapiReqIeLength = 0;
+ if(session->pWapiReqIE)
+ {
+ vos_mem_free(session->pWapiReqIE);
+ session->pWapiReqIE = NULL;
+ }
+#endif
+ /* length is two bytes */
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+#ifdef FEATURE_WLAN_ESE
+ if(eWNI_SME_JOIN_REQ == message_type)
+ {
+ /*
+ * Never include the cckmIE in an Join Request
+ * length is two bytes
+ */
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+ else if(eWNI_SME_REASSOC_REQ == message_type)
+ {
+ /* cckmIE */
+ if( csrIsProfileESE(profile))
+ {
+ /* Insert the CCKM IE into the join request */
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+ ie_len = session->suppCckmIeInfo.cckmIeLen;
+ vos_mem_copy((void *) (wpa_rsn_ie),
+ session->suppCckmIeInfo.cckmIe, ie_len);
+#else
+ ie_len = csrConstructEseCckmIe(mac,
+ session,
+ profile,
+ bss_description,
+ session->pWpaRsnReqIE,
+ session->nWpaRsnReqIeLength,
+ (void *)(wpa_rsn_ie));
+#endif
+ }
+ else
+ {
+ ie_len = 0;
+ }
+ /*
+ * If present, copy the IE into the eWNI_SME_REASSOC_REQ
+ * message buffer
+ */
+ if(ie_len)
+ {
+ /* Copy the CCKM IE over from the temp buffer (wpaRsnIE) */
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, wpa_rsn_ie, ie_len);
+ buf += ie_len;
+ }
+ else
+ {
+ /* Indicate you have no CCKM IE length is two bytes */
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+ }
+#endif
+ /* addIEScan */
+ if (profile->nAddIEScanLength)
+ {
+ ie_len = profile->nAddIEScanLength;
+ memset(session->addIEScan, 0 , session->nAddIEScanLength);
+ session->nAddIEScanLength = ie_len;
+ vos_mem_copy(session->addIEScan, profile->addIEScan, ie_len);
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, profile->addIEScan, ie_len);
+ buf += ie_len;
+ }
+ else
+ {
+ memset(session->addIEScan, 0, session->nAddIEScanLength);
+ session->nAddIEScanLength = 0;
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+ /* addIEAssoc */
+ if(profile->nAddIEAssocLength && profile->pAddIEAssoc)
+ {
+ ie_len = profile->nAddIEAssocLength;
+ if(ie_len > session->nAddIEAssocLength)
+ {
+ if(session->pAddIEAssoc && session->nAddIEAssocLength)
+ {
+ vos_mem_free(session->pAddIEAssoc);
+ }
+ session->pAddIEAssoc = vos_mem_malloc(ie_len);
+ if (NULL == session->pAddIEAssoc)
+ status = eHAL_STATUS_FAILURE;
+ else
+ status = eHAL_STATUS_SUCCESS;
+ if(!HAL_STATUS_SUCCESS(status)) break;
+ }
+ session->nAddIEAssocLength = ie_len;
+ vos_mem_copy(session->pAddIEAssoc, profile->pAddIEAssoc, ie_len);
+ w_tmp = pal_cpu_to_be16(ie_len);
+ vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16));
+ buf += sizeof(tANI_U16);
+ vos_mem_copy(buf, profile->pAddIEAssoc, ie_len);
+ buf += ie_len;
+ }
+ else
+ {
+ session->nAddIEAssocLength = 0;
+ if(session->pAddIEAssoc)
+ {
+ vos_mem_free(session->pAddIEAssoc);
+ session->pAddIEAssoc = NULL;
+ }
+ *buf = 0;
+ *(buf + 1) = 0;
+ buf += 2;
+ }
+
+ if(eWNI_SME_REASSOC_REQ == message_type )
+ {
+ /*Unmask any AC in reassoc that is ACM-set */
+ uapsd_mask = (v_U8_t)profile->uapsd_mask;
+ if( uapsd_mask && (NULL != bss_description))
+ {
+ if( CSR_IS_QOS_BSS(ies) && CSR_IS_UAPSD_BSS(ies) )
+ {
+#ifndef WLAN_MDM_CODE_REDUCTION_OPT
+ acm_mask = sme_QosGetACMMask(mac, bss_description, ies);
+#endif
+ }
+ else
+ {
+ uapsd_mask = 0;
+ }
+ }
+ }
+
+ dw_tmp = pal_cpu_to_be32(csrTranslateEncryptTypeToEdType(
+ profile->negotiatedUCEncryptionType));
+ vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+ buf += sizeof(tANI_U32);
+
+ dw_tmp = pal_cpu_to_be32(csrTranslateEncryptTypeToEdType(
+ profile->negotiatedMCEncryptionType));
+ vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+ buf += sizeof(tANI_U32);
+#ifdef WLAN_FEATURE_11W
+ /* MgmtEncryption */
+ if (profile->MFPEnabled)
+ {
+ dw_tmp = pal_cpu_to_be32(eSIR_ED_AES_128_CMAC);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(eSIR_ED_NONE);
+ }
+ vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32));
+ buf += sizeof(tANI_U32);
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ profile->MDID.mdiePresent = bss_description->mdiePresent;
+ if (csrIsProfile11r(profile)
+#ifdef FEATURE_WLAN_ESE
+ && !((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) &&
+ (ies->ESEVersion.present) &&
+ (mac->roam.configParam.isEseIniFeatureEnabled))
+#endif
+ )
+ {
+ /* is11Rconnection */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)) ;
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ /* is11Rconnection */
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+#endif
+#ifdef FEATURE_WLAN_ESE
+
+ /* isESEFeatureIniEnabled */
+ if (TRUE == mac->roam.configParam.isEseIniFeatureEnabled)
+ {
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+
+ /* A profile can not be both ESE and 11R. But an 802.11R AP
+ * may be advertising support for ESE as well. So if we are
+ * associating Open or explicitly ESE then we will get ESE.
+ * If we are associating explictly 11R only then we will get
+ * 11R.
+ */
+ if ((csrIsProfileESE(profile) ||
+ ((ies->ESEVersion.present)
+ && ((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_8021X_SHA256)
+#endif
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
+ && (mac->roam.configParam.isEseIniFeatureEnabled))
+ {
+ /* isESEconnection */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ /* isESEconnection */
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+
+ if (eWNI_SME_JOIN_REQ == message_type)
+ {
+ tESETspecInfo eseTspec;
+ /*
+ * ESE-Tspec IEs in the ASSOC request is presently not supported
+ * so nullify the TSPEC parameters
+ */
+ vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+ vos_mem_copy(buf, &eseTspec, sizeof(tESETspecInfo));
+ buf += sizeof(tESETspecInfo);
+ }
+ else if (eWNI_SME_REASSOC_REQ == message_type)
+ {
+ if ((csrIsProfileESE(profile) ||
+ ((ies->ESEVersion.present)
+ && ((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
+ || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_8021X_SHA256)
+#endif
+ || (profile->negotiatedAuthType ==
+ eCSR_AUTH_TYPE_RSN_PSK))))
+ && (mac->roam.configParam.isEseIniFeatureEnabled))
+ {
+ tESETspecInfo eseTspec;
+ /* ESE Tspec information */
+ vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+ eseTspec.numTspecs = sme_QosESERetrieveTspecInfo(mac, session_id,
+ (tTspecInfo *) &eseTspec.tspec[0]);
+ *buf = eseTspec.numTspecs;
+ buf += sizeof(tANI_U8);
+ // Copy the TSPEC information only if present
+ if (eseTspec.numTspecs) {
+ vos_mem_copy(buf, (void*)&eseTspec.tspec[0],
+ (eseTspec.numTspecs*sizeof(tTspecInfo)));
+ }
+ buf += sizeof(eseTspec.tspec);
+ }
+ else
+ {
+ tESETspecInfo eseTspec;
+ /*
+ * ESE-Tspec IEs in the ASSOC request is presently
+ * not supported so nullify the TSPEC parameters
+ */
+ vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0);
+ vos_mem_copy(buf, &eseTspec, sizeof(tESETspecInfo));
+ buf += sizeof(tESETspecInfo);
+ }
+ }
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ /* Fill in isFastTransitionEnabled */
+ if (mac->roam.configParam.isFastTransitionEnabled
+#ifdef FEATURE_WLAN_LFR
+ || csrRoamIsFastRoamEnabled(mac, session_id)
+#endif
+ )
+ {
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+#endif
+#ifdef FEATURE_WLAN_LFR
+ if(csrRoamIsFastRoamEnabled(mac, session_id))
+ {
+ /* legacy fast roaming enabled */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+#endif
+
+ /* txLdpcIniFeatureEnabled */
+ *buf = (tANI_U8)mac->roam.configParam.txLdpcEnable;
+ buf++;
+
+ if ((csrIs11hSupported(mac)) &&
+ (CSR_IS_CHANNEL_5GHZ(bss_description->channelId)) &&
+ (ies->Country.present) &&\
+ (!mac->roam.configParam.fSupplicantCountryCodeHasPriority))
+ {
+ csrSaveToChannelPower2G_5G(mac,
+ ies->Country.num_triplets * sizeof(tSirMacChanInfo),
+ (tSirMacChanInfo *)(&ies->Country.triplets[0]));
+ csrApplyPower2Current(mac);
+ }
+
+#ifdef WLAN_FEATURE_11AC
+ /* txBFIniFeatureEnabled */
+ *buf = (tANI_U8)mac->roam.configParam.txBFEnable;
+ buf++;
+
+ /* txBFCsnValue */
+ if (IS_BSS_VHT_CAPABLE(ies->VHTCaps))
+ {
+ tx_bf_csn_value = (tANI_U8)mac->roam.configParam.txBFCsnValue;
+ if (ies->VHTCaps.numSoundingDim)
+ tx_bf_csn_value = CSR_ROAM_MIN
+ (tx_bf_csn_value, ies->VHTCaps.numSoundingDim);
+ }
+ *buf = tx_bf_csn_value;
+ buf++;
+
+ /* Only enable MuBf if no other MuBF session exist
+ * and FW and HOST is MuBF capable.
+ */
+ if (IS_MUMIMO_BFORMEE_CAPABLE && (FALSE == mac->isMuBfsessionexist))
+ {
+ *buf = (tANI_U8)mac->roam.configParam.txMuBformee;
+ buf++;
+ }
+ else
+ {
+ *buf = 0;
+ buf++;
+ }
+#endif
+ *buf = (tANI_U8)mac->roam.configParam.isAmsduSupportInAMPDU;
+ buf++;
+
+ /* WME */
+ if(mac->roam.roamSession[session_id].fWMMConnection)
+ {
+ /* WME enabled */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+
+ /* QOS */
+ if(mac->roam.roamSession[session_id].fQOSConnection)
+ {
+ /* QOS enabled */
+ dw_tmp = pal_cpu_to_be32(TRUE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ else
+ {
+ dw_tmp = pal_cpu_to_be32(FALSE);
+ vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool));
+ buf += sizeof(tAniBool);
+ }
+ /* BssDesc */
+ csrPrepareJoinReassocReqBuffer(mac, bss_description, buf,
+ (tANI_U8)profile->uapsd_mask);
+ } while( 0 );
+
+ smsLog(mac, LOG1, FL("status %d"), status);
+
+ vos_mem_free(profile);
+ return status;
+}
+#endif
+
//
eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode )
{
@@ -15450,7 +16204,7 @@
}
return (nRet);
}
-static void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid)
+void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid)
{
VOS_STATUS status = VOS_STATUS_SUCCESS;
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index e9ce0c7..beb4592 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -9174,6 +9174,25 @@
vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, (tANI_U8 *) macHeader->bssId, sizeof(tSirMacAddr));
pBssDescr->nReceivedTime = vos_timer_get_system_time();
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ // MobilityDomain
+ pBssDescr->mdie[0] = 0;
+ pBssDescr->mdie[1] = 0;
+ pBssDescr->mdie[2] = 0;
+ pBssDescr->mdiePresent = FALSE;
+ // If mdie is present in the probe resp we fill it in the bss description
+ if(pParsedFrame->mdiePresent)
+ {
+ pBssDescr->mdiePresent = TRUE;
+ pBssDescr->mdie[0] = pParsedFrame->mdie[0];
+ pBssDescr->mdie[1] = pParsedFrame->mdie[1];
+ pBssDescr->mdie[2] = pParsedFrame->mdie[2];
+ }
+ smsLog(pMac, LOG1, FL("mdie=%02x%02x%02x"),
+ (unsigned int)pBssDescr->mdie[0], (unsigned int)pBssDescr->mdie[1],
+ (unsigned int)pBssDescr->mdie[2]);
+#endif
+
smsLog( pMac, LOG1, FL("Bssid= "MAC_ADDRESS_STR
" chan= %d, rssi = %d "),
MAC_ADDR_ARRAY(pBssDescr->bssId),
diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h
index a57a09c..2f57205 100644
--- a/CORE/SME/src/csr/csrInsideApi.h
+++ b/CORE/SME/src/csr/csrInsideApi.h
@@ -273,6 +273,10 @@
void csrRoamJoinedStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf );
tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp );
void csrReleaseCommandRoam(tpAniSirGlobal pMac, tSmeCmd *pCommand);
+tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac,
+ tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry);
+v_U8_t *csrNeighborRoamStateToString(v_U8_t state);
+void csrReleaseCommandPreauth(tpAniSirGlobal pMac, tSmeCmd *pCommand);
void csrReleaseCommandScan(tpAniSirGlobal pMac, tSmeCmd *pCommand);
void csrReleaseCommandWmStatusChange(tpAniSirGlobal pMac, tSmeCmd *pCommand);
//pIes2 can be NULL
@@ -402,6 +406,10 @@
eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription,
tCsrRoamProfile *pProfile, tDot11fBeaconIEs *pIes, tANI_U16 messageType );
eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode );
+#ifdef WLAN_FEATURE_LFR_MBB
+eHalStatus csr_fill_reassoc_req(tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription,
+ tDot11fBeaconIEs *pIes, tSirSmeJoinReq **reassoc_req);
+#endif
eHalStatus csrSendMBDeauthReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode );
eHalStatus csrSendMBDisassocCnfMsg( tpAniSirGlobal pMac, tpSirSmeDisassocInd pDisassocInd );
eHalStatus csrSendMBDeauthCnfMsg( tpAniSirGlobal pMac, tpSirSmeDeauthInd pDeauthInd );
diff --git a/CORE/SME/src/csr/csrNeighborRoam.c b/CORE/SME/src/csr/csrNeighborRoam.c
index da1f2cf..6bebe7a 100644
--- a/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/CORE/SME/src/csr/csrNeighborRoam.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -72,6 +72,9 @@
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
#include "csrEse.h"
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1
#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG
@@ -112,6 +115,9 @@
CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN );
CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING );
CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE );
+#ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC);
+#endif
default:
return "eCSR_NEIGHBOR_ROAM_STATE_UNKNOWN";
}
@@ -253,6 +259,36 @@
tpCsrNeighborRoamControlInfo pNeighborRoamInfo)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ smsLog(pMac, LOG1, FL("enable_lfr_mbb %d is mbb supported %d"),
+ pMac->roam.configParam.enable_lfr_mbb,
+ sme_IsFeatureSupportedByFW(MAKE_BEFORE_BREAK));
+
+ if (pMac->roam.configParam.enable_lfr_mbb
+ && sme_IsFeatureSupportedByFW(MAKE_BEFORE_BREAK)
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ && (!pNeighborRoamInfo->is11rAssoc)
+#endif
+#ifdef FEATURE_WLAN_ESE
+ && (!pNeighborRoamInfo->isESEAssoc)
+#endif
+ ) {
+ smsLog(pMac, LOG1,
+ FL("Issuing preauth reassoc"));
+ status = csr_neighbor_roam_issue_preauth_reassoc(pMac);
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+ smsLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ pMac->ft.ftSmeContext.is_preauth_lfr_mbb);
+ }
+ return status;
+ }
+
+
+#endif
+
#ifdef WLAN_FEATURE_VOWIFI_11R
if ((pNeighborRoamInfo->is11rAssoc)
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
@@ -4442,6 +4478,10 @@
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
}
#endif
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ csr_stop_preauth_reassoc_mbb_timer(pMac);
+#endif
break;
case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
@@ -4560,6 +4600,9 @@
switch (pNeighborRoamInfo->neighborRoamState)
{
+#ifdef WLAN_FEATURE_LFR_MBB
+ case eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC:
+#endif
case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
if (VOS_STATUS_SUCCESS != vosStatus)
{
@@ -5282,7 +5325,14 @@
(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING == pMac->roam.neighborRoamInfo.neighborRoamState) ||
(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE == pMac->roam.neighborRoamInfo.neighborRoamState) ||
(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState) ||
- (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState);
+ (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState)
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ || (eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC ==
+ pMac->roam.neighborRoamInfo.neighborRoamState);
+#else
+ ;
+#endif
return (val);
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
diff --git a/CORE/SME/src/csr/csr_roam_mbb.c b/CORE/SME/src/csr/csr_roam_mbb.c
new file mode 100644
index 0000000..840dbf8
--- /dev/null
+++ b/CORE/SME/src/csr/csr_roam_mbb.c
@@ -0,0 +1,848 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "aniGlobal.h"
+#include "smeInside.h"
+#include "csrInsideApi.h"
+#include "smsDebug.h"
+#include "macTrace.h"
+#include "csrNeighborRoam.h"
+#include "csr_roam_mbb.h"
+#include "csrInternal.h"
+#include "wlan_qct_wda.h"
+
+eHalStatus csr_register_roaming_mbb_callback(tpAniSirGlobal mac);
+
+#define PREAUTH_REASSOC_MBB_TIMER_VALUE 60
+
+#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\
+{\
+ mac->roam.neighborRoamInfo.prevNeighborRoamState = mac->roam.neighborRoamInfo.neighborRoamState;\
+ mac->roam.neighborRoamInfo.neighborRoamState = newState;\
+ VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, \
+ FL("Neighbor Roam Transition from state %s ==> %s"), \
+ csrNeighborRoamStateToString (mac->roam.neighborRoamInfo.prevNeighborRoamState), \
+ csrNeighborRoamStateToString (newState));\
+}
+
+/**
+ * csr_roam_issue_preauth_reassoc_req() -Prepares preauth request
+ * @hal: HAL context
+ * @session_id: session id
+ * @bss_description: BSS description
+ *
+ * This function prepares preauth request and sends request to PE
+ *
+ * Return: eHAL_STATUS_SUCCESS on success,
+ * : eHAL_STATUS_RESOURCES when resource allocation is failure
+ * : eHAL_STATUS_FAILURE otherwise
+ */
+eHalStatus csr_roam_issue_preauth_reassoc_req(tHalHandle hal,
+ tANI_U32 session_id, tpSirBssDescription bss_description)
+{
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ tpSirFTPreAuthReq pre_auth_req;
+ tANI_U16 auth_req_len = 0;
+ tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id);
+
+ auth_req_len = sizeof(tSirFTPreAuthReq);
+ pre_auth_req = (tpSirFTPreAuthReq)vos_mem_malloc(auth_req_len);
+ if (NULL == pre_auth_req) {
+ smsLog(mac, LOGE,
+ FL("Memory allocation for Preauth request failed"));
+ return eHAL_STATUS_RESOURCES;
+ }
+
+ /*
+ * If neighborRoamState is eCSR_NEIGHBOR_ROAM_STATE_INIT
+ * by the time this API is invoked, disconnect would have happened.
+ * So, need to proceed further.
+ */
+ if (mac->roam.neighborRoamInfo.neighborRoamState ==
+ eCSR_NEIGHBOR_ROAM_STATE_INIT) {
+ smsLog(mac, LOGE, FL("neighborRoamState %d"),
+ mac->roam.neighborRoamInfo.neighborRoamState);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ /*
+ * Save the SME Session ID here. We need it while processing
+ * the preauth response.
+ */
+ mac->ft.ftSmeContext.smeSessionId = session_id;
+ vos_mem_zero(pre_auth_req, auth_req_len);
+
+ pre_auth_req->pbssDescription = (tpSirBssDescription)vos_mem_malloc(
+ sizeof(bss_description->length) + bss_description->length);
+ if (NULL == pre_auth_req->pbssDescription) {
+ smsLog(mac, LOGE,
+ FL("Unable to allocate memory for preauth bss description"));
+ return eHAL_STATUS_RESOURCES;
+ }
+
+ pre_auth_req->messageType =
+ pal_cpu_to_be16(eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ);
+
+ pre_auth_req->preAuthchannelNum = bss_description->channelId;
+
+ vos_mem_copy((void *)&pre_auth_req->currbssId,
+ (void *)session->connectedProfile.bssid, sizeof(tSirMacAddr));
+ vos_mem_copy((void *)&pre_auth_req->preAuthbssId,
+ (void *)bss_description->bssId, sizeof(tSirMacAddr));
+
+ vos_mem_copy(pre_auth_req->pbssDescription, bss_description,
+ sizeof(bss_description->length) + bss_description->length);
+ pre_auth_req->length = pal_cpu_to_be16(auth_req_len);
+
+ /* Register mbb callback */
+ smsLog(mac, LOG1, FL("Registering mbb callback"));
+ csr_register_roaming_mbb_callback(mac);
+
+ return palSendMBMessage(mac->hHdd, pre_auth_req);
+}
+
+/**
+ * csr_neighbor_roam_issue_preauth_reassoc() -issues preauth_reassoc request
+ * @mac: MAC context
+ *
+ * This function issues preauth_reassoc request to PE with the 1st AP
+ * entry in the roamable AP list
+ *
+ * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
+ */
+eHalStatus csr_neighbor_roam_issue_preauth_reassoc(tpAniSirGlobal mac)
+{
+ tpCsrNeighborRoamControlInfo neighbor_roam_info =
+ &mac->roam.neighborRoamInfo;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpCsrNeighborRoamBSSInfo neighbor_bss_node;
+ tCsrRoamInfo roam_info;
+
+ VOS_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending ==
+ eANI_BOOLEAN_FALSE);
+
+ neighbor_bss_node = csrNeighborRoamGetRoamableAPListNextEntry(mac,
+ &neighbor_roam_info->roamableAPList, NULL);
+
+ if (neighbor_bss_node == NULL)
+ {
+ smsLog(mac, LOGE, FL("Roamable AP list is empty"));
+ csrRoamOffloadScan(mac, ROAM_SCAN_OFFLOAD_RESTART,
+ REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+ return eHAL_STATUS_FAILURE;
+ }
+ else
+ {
+ /*
+ * Set is_preauth_lfr_mbb which will be checked in
+ * different API's.
+ */
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb = true;
+ smsLog(mac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
+ status = csrRoamEnqueuePreauth(mac,
+ neighbor_roam_info->csrSessionId,
+ neighbor_bss_node->pBssDescription,
+ ecsr_mbb_perform_preauth_reassoc,
+ eANI_BOOLEAN_TRUE);
+
+ smsLog(mac, LOG1, FL("Before Pre-Auth: BSSID "MAC_ADDRESS_STR", Ch:%d"),
+ MAC_ADDR_ARRAY(neighbor_bss_node->pBssDescription->bssId),
+ neighbor_bss_node->pBssDescription->channelId);
+
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ smsLog(mac, LOGE,
+ FL("Send Preauth request to PE failed with status %d"),
+ status);
+ return status;
+ }
+ }
+
+ neighbor_roam_info->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
+
+ CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC)
+
+ if (csrRoamIsFastRoamEnabled(mac, CSR_SESSION_ID_INVALID))
+ {
+ smsLog(mac, LOG1, FL("Invoking eCSR_ROAM_PMK_NOTIFY"));
+ vos_mem_copy((void *)&roam_info.bssid,
+ (void *)neighbor_bss_node->pBssDescription->bssId,
+ sizeof(tCsrBssid));
+ csrRoamCallCallback(mac, neighbor_roam_info->csrSessionId, &roam_info,
+ 0, eCSR_ROAM_PMK_NOTIFY, 0);
+ }
+ return status;
+}
+
+/**
+ * csr_stop_preauth_reassoc_mbb_timer() -stops preauth_reassoc timer
+ * @mac: MAC context
+ *
+ * This function stops preauth_reassoc timer
+ *
+ */
+void csr_stop_preauth_reassoc_mbb_timer(tpAniSirGlobal mac)
+{
+ VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+
+ smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"),
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started);
+
+ if (mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started) {
+ vos_status =
+ vos_timer_stop(&mac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer);
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started =
+ false;
+ }
+
+ smsLog(mac, LOG1, FL("vos_status %d"), vos_status);
+}
+
+
+/**
+ * csr_preauth_reassoc_mbb_timer_callback() -preauth_reassoc timer callback
+ * @mac: MAC context
+ *
+ * This function issues preauth_reassoc with another roamable entry
+ *
+ */
+void csr_preauth_reassoc_mbb_timer_callback(void *context)
+{
+ tpAniSirGlobal mac = (tpAniSirGlobal)context;
+
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = 0;
+
+ smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"),
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started);
+
+ csr_neighbor_roam_issue_preauth_reassoc(mac);
+}
+
+
+/**
+ * csr_roam_dequeue_preauth_reassoc() -Dequeues
+ * ecsr_mbb_perform_preauth_reassoc
+ * @mac: MAC context
+ *
+ * This function dequeues ecsr_mbb_perform_preauth_reassoc
+ *
+ */
+eHalStatus csr_roam_dequeue_preauth_reassoc(tpAniSirGlobal mac)
+{
+ tListElem *entry;
+ tSmeCmd *command;
+ entry = csrLLPeekHead(&mac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+ if (entry) {
+ command = GET_BASE_ADDR(entry, tSmeCmd, Link);
+ if ((eSmeCommandRoam == command->command) &&
+ (ecsr_mbb_perform_preauth_reassoc ==
+ command->u.roamCmd.roamReason)) {
+ smsLog(mac, LOG1, FL("DQ-Command = %d, Reason = %d"),
+ command->command, command->u.roamCmd.roamReason);
+ if (csrLLRemoveEntry( &mac->sme.smeCmdActiveList,
+ entry, LL_ACCESS_LOCK)) {
+ csrReleaseCommandPreauth( mac, command );
+ }
+ } else {
+ smsLog(mac, LOGE, FL("Command = %d, Reason = %d "),
+ command->command, command->u.roamCmd.roamReason);
+ }
+ }
+ else {
+ smsLog(mac, LOGE,
+ FL("pEntry NULL for eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP"));
+ }
+ smeProcessPendingQueue( mac );
+ return eHAL_STATUS_SUCCESS;
+}
+
+/**
+ * csr_neighbor_roam_preauth_reassoc_rsp_handler() -handles preauth
+ * reassoc response
+ * @mac: MAC context
+ * @lim_status: status of preauth reassoc response from lim
+ * @bss_description: bss description pointer
+ *
+ * This function handles preauth_reassoc response from PE. When
+ * preauth_reassoc response failure is received, preauth reassoc
+ * with new candidate will be attempted. In success case, candidate will be
+ * removed from roamable entry.
+ *
+ */
+eHalStatus
+csr_neighbor_roam_preauth_reassoc_rsp_handler(tpAniSirGlobal mac,
+ tSirRetStatus lim_status, tSirBssDescription **bss_description)
+{
+ tpCsrNeighborRoamControlInfo neighbor_roam_info =
+ &mac->roam.neighborRoamInfo;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ eHalStatus preauth_processed = eHAL_STATUS_SUCCESS;
+ tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL;
+
+ if (eANI_BOOLEAN_FALSE ==
+ neighbor_roam_info->FTRoamInfo.preauthRspPending) {
+ /*
+ * This can happen when we disconnect immediately after sending
+ * a pre-auth request. During processing of the disconnect command,
+ * we would have reset preauthRspPending and transitioned to INIT state.
+ */
+ smsLog(mac, LOGE,
+ FL("Unexpected pre-auth response in state %d"),
+ neighbor_roam_info->neighborRoamState);
+ preauth_processed = eHAL_STATUS_FAILURE;
+ goto DEQ_PREAUTH;
+ }
+
+ if ((neighbor_roam_info->neighborRoamState !=
+ eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC)) {
+ smsLog(mac, LOGE,
+ FL("Preauth response received in state %s"),
+ macTraceGetNeighbourRoamState(
+ neighbor_roam_info->neighborRoamState));
+ preauth_processed = eHAL_STATUS_FAILURE;
+ goto DEQ_PREAUTH;
+ }
+
+ neighbor_roam_info->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
+
+ if (eSIR_SUCCESS == lim_status)
+ preauth_rsp_node = csrNeighborRoamGetRoamableAPListNextEntry(mac,
+ &neighbor_roam_info->roamableAPList, NULL);
+
+ if ((eSIR_SUCCESS == lim_status) && (NULL != preauth_rsp_node)) {
+ smsLog(mac, LOG1, FL("MBB Reassoc completed successfully"));
+
+ smsLog(mac, LOG1, FL("After MBB reassoc BSSID "MAC_ADDRESS_STR" Ch %d"),
+ MAC_ADDR_ARRAY(preauth_rsp_node->pBssDescription->bssId),
+ preauth_rsp_node->pBssDescription->channelId);
+
+ /* Memory will be freed in caller of this */
+ *bss_description = (tpSirBssDescription)vos_mem_malloc(
+ sizeof(preauth_rsp_node->pBssDescription->length) +
+ preauth_rsp_node->pBssDescription->length);
+ if (NULL == *bss_description) {
+ smsLog(mac, LOGE,
+ FL("Unable to allocate memory for preauth bss description"));
+ preauth_processed = eHAL_STATUS_RESOURCES;
+ goto DEQ_PREAUTH;
+ }
+
+ vos_mem_copy(*bss_description, preauth_rsp_node->pBssDescription,
+ sizeof(preauth_rsp_node->pBssDescription->length) +
+ preauth_rsp_node->pBssDescription->length);
+
+ /*
+ * MBB Reassoc competer successfully. Insert the preauthenticated
+ * node to tail of preAuthDoneList
+ */
+ csrNeighborRoamRemoveRoamableAPListEntry(mac,
+ &neighbor_roam_info->roamableAPList, preauth_rsp_node);
+ csrLLInsertTail(&neighbor_roam_info->FTRoamInfo.preAuthDoneList,
+ &preauth_rsp_node->List, LL_ACCESS_LOCK);
+ return eHAL_STATUS_SUCCESS;
+ } else {
+ tpCsrNeighborRoamBSSInfo neighbor_bss_node = NULL;
+ tListElem *entry;
+
+ /*
+ * Pre-auth failed. Add the bssId to the preAuth failed list MAC Address.
+ * Also remove the AP from roamable AP list. The one in the head of the
+ * list should be one with which we issued pre-auth and failed.
+ */
+ entry = csrLLRemoveHead(&neighbor_roam_info->roamableAPList,
+ LL_ACCESS_LOCK);
+ if(entry) {
+ neighbor_bss_node = GET_BASE_ADDR(entry,
+ tCsrNeighborRoamBSSInfo, List);
+ /*
+ * Add the BSSID to pre-auth fail list if it is
+ * not requested by HDD
+ */
+ status = csrNeighborRoamAddBssIdToPreauthFailList(mac,
+ neighbor_bss_node->pBssDescription->bssId);
+
+ smsLog(mac, LOG1,
+ FL("MBB reassoc failed BSSID "MAC_ADDRESS_STR" Ch:%d status %d"),
+ MAC_ADDR_ARRAY(neighbor_bss_node->pBssDescription->bssId),
+ neighbor_bss_node->pBssDescription->channelId, lim_status);
+
+ /* Now we can free this node */
+ csrNeighborRoamFreeNeighborRoamBSSNode(mac, neighbor_bss_node);
+ }
+
+ /*
+ * Move state to Connected. Connected state here signifies connection
+ * with current AP as preauth failed with roamable AP. Still driver has
+ * connection with current AP.
+ */
+ CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
+
+ /* Start a timer to issue preauth_reassoc request for the next entry*/
+ status = vos_timer_start(&mac->ft.ftSmeContext.
+ pre_auth_reassoc_mbb_timer, PREAUTH_REASSOC_MBB_TIMER_VALUE);
+ if (eHAL_STATUS_SUCCESS != status) {
+ smsLog(mac, LOGE,
+ FL("pre_auth_reassoc_mbb_timer start failed status %d"),
+ status);
+ preauth_processed = eHAL_STATUS_FAILURE;
+ goto DEQ_PREAUTH;
+ }
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = true;
+ smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"),
+ mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started);
+ preauth_processed = eHAL_STATUS_SUCCESS;
+ }
+
+DEQ_PREAUTH:
+ csr_roam_dequeue_preauth_reassoc(mac);
+ return preauth_processed;
+}
+
+eHalStatus csr_update_roamed_info_mbb(tHalHandle hal,
+ tpSirBssDescription bss_description, tpSirFTPreAuthRsp pre_auth_rsp)
+{
+ eHalStatus status;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ tDot11fBeaconIEs *ies_local = NULL;
+ tCsrRoamSession *session = NULL;
+ tCsrRoamProfile *profile;
+ tSirMacAddr broadcast_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ tANI_U32 key_timeout_interval;
+ tCsrRoamInfo roam_info;
+ sme_QosAssocInfo assoc_info;
+ tANI_U32 len;
+ tANI_U8 sme_session_id = pre_auth_rsp->smeSessionId;
+ tANI_U8 acm_mask = 0;
+
+ /* Get profile */
+ session = CSR_GET_SESSION(mac, sme_session_id);
+
+ if (session->abortConnection) {
+ smsLog(mac, LOGE, FL("Disconnect in progress"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ profile = vos_mem_malloc(sizeof(*profile));
+ if (NULL == profile) {
+ smsLog(mac, LOGE, FL("Memory allocation failure for profile"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ status = csrRoamCopyProfile(mac, profile, session->pCurRoamProfile);
+ if(!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE, FL("Profile copy failed"));
+ vos_mem_free(profile);
+ return status;
+ }
+
+ profile->negotiatedAuthType =
+ mac->roam.roamSession[sme_session_id].connectedProfile.AuthType;
+ profile->negotiatedUCEncryptionType =
+ mac->roam.roamSession[sme_session_id].connectedProfile.EncryptionType;
+ profile->mcEncryptionType =
+ mac->roam.roamSession[sme_session_id].connectedProfile.mcEncryptionInfo;
+ profile->negotiatedMCEncryptionType =
+ mac->roam.roamSession[sme_session_id].connectedProfile.mcEncryptionType;
+
+ smsLog(mac, LOG1,
+ FL("AuthType %d UCEType %d Entries %d encryptionType %d MCEType %d"),
+ profile->negotiatedAuthType,
+ profile->negotiatedUCEncryptionType,
+ profile->mcEncryptionType.numEntries,
+ profile->mcEncryptionType.encryptionType[0],
+ profile->negotiatedMCEncryptionType);
+
+ /* Get IE's */
+ status = csrGetParsedBssDescriptionIEs(mac, bss_description, &ies_local);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE,
+ FL("csrGetParsedBssDescriptionIEs failed"));
+ return status;
+ }
+ if(ies_local == NULL) {
+ smsLog(mac, LOGE,
+ FL("ies_local is NULL "));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ vos_mem_set(&roam_info, sizeof(roam_info), 0);
+
+ csrRoamStopNetwork(mac, sme_session_id, profile,
+ bss_description, ies_local);
+
+ session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+
+ csrRoamSaveConnectedInfomation(mac, sme_session_id, profile,
+ bss_description, ies_local);
+ csrRoamSaveSecurityRspIE(mac, sme_session_id,
+ profile->negotiatedAuthType, bss_description,
+ ies_local);
+
+ csrRoamStateChange(mac, eCSR_ROAMING_STATE_JOINED, sme_session_id);
+
+ if(CSR_IS_ENC_TYPE_STATIC(profile->negotiatedUCEncryptionType) &&
+ !profile->bWPSAssociation) {
+ /*
+ * Issue the set Context request to LIM to establish the
+ * Unicast STA context
+ */
+ if(!HAL_STATUS_SUCCESS(csrRoamIssueSetContextReq(mac,
+ sme_session_id,
+ profile->negotiatedUCEncryptionType,
+ bss_description, &(bss_description->bssId), FALSE, TRUE,
+ eSIR_TX_RX, 0, 0, NULL, 0))) {
+ smsLog(mac, LOGE, FL("Set context for unicast fail"));
+ csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_NONE,
+ sme_session_id);
+ }
+ /*
+ * Issue the set Context request to LIM to establish the
+ * Broadcast STA context
+ */
+ csrRoamIssueSetContextReq(mac, sme_session_id,
+ profile->negotiatedMCEncryptionType,
+ bss_description, &broadcast_mac,
+ FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0);
+ } else if (!session->abortConnection) {
+ /* Need to wait for supplicant authtication */
+ roam_info.fAuthRequired = eANI_BOOLEAN_TRUE;
+ /* Set the subestate to WaitForKey in case authentiation is needed */
+ csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
+ sme_session_id);
+
+ if(profile->bWPSAssociation)
+ key_timeout_interval = CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD;
+ else
+ key_timeout_interval = CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD;
+
+ /* Save sessionId in case of timeout */
+ mac->roam.WaitForKeyTimerInfo.sessionId = sme_session_id;
+ /*
+ * This time should be long enough for the rest of the
+ * process plus setting key
+ */
+ if(!HAL_STATUS_SUCCESS(csrRoamStartWaitForKeyTimer(mac,
+ key_timeout_interval))) {
+ /* Reset our state so nothting is blocked */
+ smsLog(mac, LOGE, FL("Failed to start pre-auth timer"));
+ csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_NONE,
+ sme_session_id);
+ }
+ }
+
+ csrRoamFreeConnectedInfo(mac, &session->connectedInfo);
+
+ assoc_info.pBssDesc = bss_description;
+ assoc_info.pProfile = profile;
+
+ len = pre_auth_rsp->roam_info->nBeaconLength +
+ pre_auth_rsp->roam_info->nAssocReqLength +
+ pre_auth_rsp->roam_info->nAssocRspLength;
+
+ if(len) {
+ session->connectedInfo.pbFrames = vos_mem_malloc(len);
+ if (session->connectedInfo.pbFrames != NULL ) {
+ vos_mem_copy(session->connectedInfo.pbFrames,
+ pre_auth_rsp->roam_info->pbFrames, len);
+ session->connectedInfo.nAssocReqLength =
+ pre_auth_rsp->roam_info->nAssocReqLength;
+ session->connectedInfo.nAssocRspLength =
+ pre_auth_rsp->roam_info->nAssocRspLength;
+ session->connectedInfo.nBeaconLength =
+ pre_auth_rsp->roam_info->nBeaconLength;
+
+ roam_info.nAssocReqLength = pre_auth_rsp->roam_info->nAssocReqLength;
+ roam_info.nAssocRspLength = pre_auth_rsp->roam_info->nAssocRspLength;
+ roam_info.nBeaconLength = pre_auth_rsp->roam_info->nBeaconLength;
+ roam_info.pbFrames = session->connectedInfo.pbFrames;
+ }
+ session->connectedInfo.staId = pre_auth_rsp->roam_info->staId;
+ roam_info.staId = pre_auth_rsp->roam_info->staId;
+ roam_info.ucastSig = pre_auth_rsp->roam_info->ucastSig;
+ roam_info.bcastSig = pre_auth_rsp->roam_info->bcastSig;
+ roam_info.maxRateFlags = pre_auth_rsp->roam_info->maxRateFlags;
+ }
+
+ roam_info.statusCode = eSIR_SME_SUCCESS;
+ roam_info.reasonCode = eSIR_SME_SUCCESS;
+ roam_info.pBssDesc = bss_description;
+
+ vos_mem_copy(&roam_info.bssid, &bss_description->bssId,
+ sizeof(tCsrBssid));
+
+ mac->roam.roamSession[sme_session_id].connectState =
+ eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+
+ sme_QosCsrEventInd(mac, sme_session_id,
+ SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL);
+ sme_QosCsrEventInd(mac, sme_session_id, SME_QOS_CSR_REASSOC_REQ, NULL);
+ sme_QosCsrEventInd(mac, sme_session_id, SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+
+ mac->roam.roamSession[sme_session_id].connectState =
+ eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+ sme_QosCsrEventInd(mac, sme_session_id,
+ SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info);
+
+
+ acm_mask = sme_QosGetACMMask(mac, bss_description, NULL);
+
+ session->connectedProfile.acm_mask = acm_mask;
+ if(session->connectedProfile.modifyProfileFields.uapsd_mask) {
+ smsLog(mac, LOGE, "uapsd_mask (0x%X) set, request UAPSD now",
+ session->connectedProfile.modifyProfileFields.uapsd_mask);
+ pmcStartUapsd(mac, NULL, NULL);
+ }
+ session->connectedProfile.dot11Mode = session->bssParams.uCfgDot11Mode;
+ roam_info.u.pConnectedProfile = &session->connectedProfile;
+
+ if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) &&
+ (csrIsConcurrentSessionRunning(mac)))
+ mac->roam.configParam.doBMPSWorkaround = 1;
+
+ csr_roam_dequeue_preauth_reassoc(mac);
+
+ csrRoamCallCallback(mac, sme_session_id, &roam_info, 0,
+ eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED);
+
+ csrResetPMKIDCandidateList(mac, sme_session_id);
+#ifdef FEATURE_WLAN_WAPI
+ csrResetBKIDCandidateList(mac, sme_session_id);
+#endif
+
+ if(!CSR_IS_WAIT_FOR_KEY(mac, sme_session_id)) {
+ smsLog(mac, LOG1, "NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up");
+ csrRoamLinkUp(mac, session->connectedProfile.bssid);
+ }
+
+ if (pmcShouldBmpsTimerRun(mac)) {
+ if(eANI_BOOLEAN_TRUE == roam_info.fAuthRequired) {
+ mac->pmc.full_power_till_set_key = true;
+ smsLog(mac, LOG1,
+ FL("full_power_till_set_key is made true"));
+ }
+
+ if (pmcStartTrafficTimer(mac, BMPS_TRAFFIC_TIMER_ALLOW_SECURITY_DHCP)
+ != eHAL_STATUS_SUCCESS)
+ smsLog(mac, LOGE, FL("Cannot start BMPS Retry timer"));
+
+ smsLog(mac, LOG1, FL("BMPS Retry Timer already running or started"));
+ }
+
+ vos_mem_free(pre_auth_rsp->roam_info->pbFrames);
+ vos_mem_free(pre_auth_rsp->roam_info);
+ vos_mem_free(profile);
+ vos_mem_free(ies_local);
+
+ return eHAL_STATUS_SUCCESS;
+}
+
+
+/**
+ * csr_roam_preauth_rsp_mbb_processor() -handles
+ * eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP
+ * @hal: HAL context
+ *
+ * This function invokes preauth reassoc response handler and
+ * updates CSR with new connection information.
+ *
+ */
+void csr_roam_preauth_rsp_mbb_processor(tHalHandle hal,
+ tpSirFTPreAuthRsp pre_auth_rsp)
+{
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ eHalStatus status;
+ tCsrRoamInfo roam_info;
+ tpSirBssDescription bss_description = NULL;
+
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb = false;
+ smsLog(mac, LOG1, FL("is_preauth_lfr_mbb %d"),
+ mac->ft.ftSmeContext.is_preauth_lfr_mbb);
+
+ /*
+ * When reason is SIR_MBB_DISCONNECTED, cleanup CSR info
+ * of connected AP.
+ */
+ if (pre_auth_rsp->reason == SIR_MBB_DISCONNECTED) {
+ /* Dequeue ecsr_perform_preauth_reassoc */
+ csr_roam_dequeue_preauth_reassoc(mac);
+
+ vos_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
+ csrRoamCallCallback(mac, pre_auth_rsp->smeSessionId, &roam_info, 0,
+ eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS);
+
+ csrRoamComplete(mac, eCsrJoinFailure, NULL);
+ }
+
+ status = csr_neighbor_roam_preauth_reassoc_rsp_handler(mac,
+ pre_auth_rsp->status, &bss_description);
+ if (status != eHAL_STATUS_SUCCESS) {
+ smsLog(mac, LOGE,FL("Preauth was not processed: %d SessionID: %d"),
+ status, pre_auth_rsp->smeSessionId);
+ /*
+ * Preauth_reassoc is dequeued already in
+ * csr_neighbor_roam_preauth_reassoc_rsp_handler for error cases.
+ */
+ return;
+ }
+
+ /*
+ * The below function calls/timers should be invoked only
+ * if the pre-auth is successful. Also, Preauth_reassoc is dequeued
+ * already in csr_neighbor_roam_preauth_reassoc_rsp_handler.
+ */
+ if (VOS_STATUS_SUCCESS != (VOS_STATUS)pre_auth_rsp->status)
+ return;
+
+ mac->ft.ftSmeContext.FTState = eFT_AUTH_COMPLETE;
+
+ /* Save the received response */
+ vos_mem_copy((void *)&mac->ft.ftSmeContext.preAuthbssId,
+ (void *)pre_auth_rsp->preAuthbssId, sizeof(tCsrBssid));
+
+
+ /*
+ * bss_description is updated in
+ * csr_neighbor_roam_preauth_reassoc_rsp_handler
+ */
+ if (NULL == bss_description) {
+ smsLog(mac, LOGE,
+ FL("bss description is NULL"));
+ goto DEQ_PREAUTH;
+ }
+
+ /* Update CSR for new connection */
+ status = csr_update_roamed_info_mbb(hal, bss_description, pre_auth_rsp);
+ /* In success case preauth reassoc is dequeued in
+ * csr_update_roamed_info_mbb before updating HDD.
+ */
+ if(HAL_STATUS_SUCCESS(status))
+ return;
+
+DEQ_PREAUTH:
+ csr_roam_dequeue_preauth_reassoc(mac);
+}
+
+/**
+ * csr_prepare_reassoc_req () - Prepares reassoc request
+ * @pmac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @preassoc_req: pointer to reassociation request
+ *
+ *Return: None
+ */
+static void csr_prepare_reassoc_req(void* pmac, tANI_U32 session_id,
+ void* pbss_description, void *preassoc_req)
+{
+ tDot11fBeaconIEs *ies_local = NULL;
+ eHalStatus status;
+ tpAniSirGlobal mac = (tpAniSirGlobal)pmac;
+ tpSirBssDescription bss_description = (tpSirBssDescription)pbss_description;
+ tSirSmeJoinReq **reassoc_req = (tSirSmeJoinReq **)preassoc_req;
+
+ /* Get IE's */
+ status = csrGetParsedBssDescriptionIEs(mac, bss_description, &ies_local);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE,
+ FL("csrGetParsedBssDescriptionIEs failed"));
+ return;
+ }
+ if(ies_local == NULL) {
+ smsLog(mac, LOGE,
+ FL("ies_local is NULL"));
+ return;
+ }
+
+ smsLog(mac, LOG1, FL("session_id %d"), session_id);
+
+ status = csr_fill_reassoc_req(mac, session_id, bss_description,
+ ies_local, reassoc_req);
+ if (!HAL_STATUS_SUCCESS(status)) {
+ smsLog(mac, LOGE,
+ FL("Reassociation request filling failed"));
+ return;
+ }
+ vos_mem_free(ies_local);
+ smsLog(mac, LOG1, FL("status %d"), status);
+}
+
+/**
+ * csr_roaming_mbb_callback () - handles mbb callback
+ * @pmac: MAC context
+ * @session_id: session id
+ * @pbss_description: bss description
+ * @preassoc_req: pointer to reassociation request
+ * @csr_roam_op_code: callback opcode
+ *
+ *Return: None
+ */
+static void csr_roaming_mbb_callback(void* pmac, tANI_U32 session_id,
+ void* pbss_description, void *preassoc_req, tANI_U32 csr_roam_op_code)
+{
+ tpAniSirGlobal mac = (tpAniSirGlobal)pmac;
+
+ smsLog(mac, LOG1,
+ FL("csr_roam_op_code %d"), csr_roam_op_code);
+
+ switch(csr_roam_op_code) {
+ case SIR_ROAMING_DEREGISTER_STA:
+ csrRoamCallCallback(mac, session_id, NULL, 0,
+ eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+ break;
+ case SIR_STOP_ROAM_OFFLOAD_SCAN:
+ csrRoamOffloadScan(mac, ROAM_SCAN_OFFLOAD_STOP, REASON_DISCONNECTED);
+ break;
+ case SIR_PREPARE_REASSOC_REQ:
+ csr_prepare_reassoc_req(pmac, session_id, pbss_description,
+ preassoc_req);
+ break;
+ }
+}
+
+/**
+ * csr_register_roaming_mbb_callback () - registers roaming callback
+ * @mac: MAC context
+ *
+ *Return: eHAL_STATUS_SUCCESS on success, otherwise failure
+ */
+eHalStatus csr_register_roaming_mbb_callback(tpAniSirGlobal mac)
+{
+ eHalStatus status;
+
+ status = sme_AcquireGlobalLock(&mac->sme);
+ if (eHAL_STATUS_SUCCESS == status) {
+ mac->sme.roaming_mbb_callback = csr_roaming_mbb_callback;
+ sme_ReleaseGlobalLock(&mac->sme);
+ } else
+ smsLog(mac, LOGE,
+ FL("sme_AcquireGlobalLock error"));
+ return status;
+}
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 0fcac9f..0dd99ae 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1537,6 +1537,10 @@
#if defined WLAN_FEATURE_VOWIFI_11R
sme_FTOpen(pMac);
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+
+#endif
+
sme_p2pOpen(pMac);
smeTraceInit(pMac);
sme_register_debug_callback();
diff --git a/CORE/SME/src/sme_common/sme_FTApi.c b/CORE/SME/src/sme_common/sme_FTApi.c
index 4d988af..c791338 100644
--- a/CORE/SME/src/sme_common/sme_FTApi.c
+++ b/CORE/SME/src/sme_common/sme_FTApi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -41,6 +41,11 @@
#include <csrNeighborRoam.h>
#include "vos_utils.h"
+#ifdef WLAN_FEATURE_LFR_MBB
+#include "csr_roam_mbb.h"
+#endif
+
+
/*--------------------------------------------------------------------------
Initialize the FT context.
------------------------------------------------------------------------*/
@@ -60,6 +65,18 @@
return;
}
vos_reset_roam_timer_log();
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ status = vos_timer_init(&pMac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer,
+ VOS_TIMER_TYPE_SW,
+ csr_preauth_reassoc_mbb_timer_callback,
+ (void *)pMac);
+
+ if (eHAL_STATUS_SUCCESS != status) {
+ smsLog(pMac, LOGE, FL("pre_auth_reassoc_mbb_timer allocation failed"));
+ return;
+ }
+#endif
}
/*--------------------------------------------------------------------------
@@ -71,6 +88,10 @@
//Clear the FT Context.
sme_FTReset(hHal);
vos_timer_destroy(&pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ vos_timer_destroy(&pMac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer);
+#endif
}
void sme_SetFTPreAuthState(tHalHandle hHal, v_BOOL_t state)
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index ff50926..ba7c97a 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -137,6 +137,9 @@
CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING);
CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
#endif /* WLAN_FEATURE_VOWIFI_11R */
+ #ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC);
+ #endif
CASE_RETURN_STRING(eNEIGHBOR_STATE_MAX);
default:
@@ -572,6 +575,10 @@
CASE_RETURN_STRING(eWNI_SME_UPDATE_MAX_RATE_IND);
CASE_RETURN_STRING(eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ);
CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_CB);
+#ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ);
+ CASE_RETURN_STRING(eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP);
+#endif
CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
CASE_RETURN_STRING(eWNI_SME_CAP_TSF_REQ);
CASE_RETURN_STRING(eWNI_SME_GET_TSF_REQ);
@@ -982,7 +989,15 @@
CASE_RETURN_STRING(SIR_LIM_DISASSOC_ACK_TIMEOUT);
CASE_RETURN_STRING(SIR_LIM_DEAUTH_ACK_TIMEOUT);
CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT);
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ CASE_RETURN_STRING(SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_REASSOC_MBB_RSP_TIMEOUT);
+
+#endif
+
CASE_RETURN_STRING(SIR_LIM_AUTH_RETRY_TIMEOUT);
+
CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END);
CASE_RETURN_STRING(LIM_MLM_SCAN_REQ);
CASE_RETURN_STRING(LIM_MLM_SCAN_CNF);
diff --git a/CORE/WDA/inc/legacy/halTypes.h b/CORE/WDA/inc/legacy/halTypes.h
index 804925a..f2f1b1f 100644
--- a/CORE/WDA/inc/legacy/halTypes.h
+++ b/CORE/WDA/inc/legacy/halTypes.h
@@ -219,6 +219,12 @@
#endif
//CMD not Queued in SME
eHAL_STATUS_CMD_NOT_QUEUED,
+
+#ifdef WLAN_FEATURE_LFR_MBB
+ eHAL_STATUS_MBB_DEL_BSS_FAIL,
+ eHAL_STATUS_MBB_ADD_BSS_FAIL,
+#endif
+
// not a real status. Just a way to mark the maximum in the enum.
eHAL_STATUS_MAX
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 96bef70..8c745d9 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -3307,6 +3307,9 @@
WDI_LINK_FINISH_CAL_STATE = 13,
WDI_LINK_LISTEN_STATE = 14,
WDI_LINK_SEND_ACTION_STATE = 15,
+#ifdef WLAN_FEATURE_LFR_MBB
+ WDI_LINK_PRE_AUTH_REASSOC_STATE = 17,
+#endif
WDI_LINK_MAX = 0x7FFFFFFF
} WDI_LinkStateType;
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 04a6add..a153bb9 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -223,7 +223,7 @@
,SAP_MODE_WOW //64
,SAP_OFFLOADS //65
,SAP_BUFF_ALLOC //66
- ,FEATURE_NOT_SUPPORTED
+ ,MAKE_BEFORE_BREAK //67
,NUD_DEBUG //68
};
@@ -2013,6 +2013,13 @@
"%s", "SAP_BUFF_ALLOC");
pCapStr += strlen("SAP_BUFF_ALLOC");
break;
+
+ case MAKE_BEFORE_BREAK:
+ snprintf(pCapStr, sizeof("MAKE_BEFORE_BREAK"),
+ "%s", "MAKE_BEFORE_BREAK");
+ pCapStr += strlen("MAKE_BEFORE_BREAK");
+ break;
+
case NUD_DEBUG:
snprintf(pCapStr, sizeof("NUD_DEBUG"),
"%s", "NUD_DEBUG");
@@ -25926,6 +25933,11 @@
case WDI_LINK_SEND_ACTION_STATE:
return eSIR_LINK_SEND_ACTION_STATE;
+#ifdef WLAN_FEATURE_LFR_MBB
+ case WDI_LINK_PRE_AUTH_REASSOC_STATE:
+ return eSIR_LINK_PRE_AUTH_REASSOC_STATE;
+#endif
+
default:
return eSIR_LINK_MAX;
}
diff --git a/Kbuild b/Kbuild
index a7d0f57..dfa683e 100644
--- a/Kbuild
+++ b/Kbuild
@@ -23,6 +23,9 @@
#Flag to enable Legacy Fast Roaming(LFR)
CONFIG_PRIMA_WLAN_LFR := y
+#Flag to enable Legacy Fast Roaming(LFR) Make Before Break
+ CONFIG_PRIMA_WLAN_LFR_MBB := y
+
#JB kernel has PMKSA patches, hence enabling this flag
CONFIG_PRIMA_WLAN_OKC := y
@@ -233,6 +236,10 @@
MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessTdls.o
endif
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_mbb.o
+endif
+
MAC_PMM_OBJS := $(MAC_SRC_DIR)/pe/pmm/pmmAP.o \
$(MAC_SRC_DIR)/pe/pmm/pmmApi.o \
$(MAC_SRC_DIR)/pe/pmm/pmmDebug.o
@@ -294,6 +301,10 @@
SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrTdlsProcess.o
endif
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csr_roam_mbb.o
+endif
+
SME_PMC_OBJS := $(SME_SRC_DIR)/pmc/pmcApi.o \
$(SME_SRC_DIR)/pmc/pmc.o \
$(SME_SRC_DIR)/pmc/pmcLogDump.o
@@ -627,6 +638,10 @@
CDEFINES += -DFEATURE_WLAN_LFR
endif
+ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y)
+CDEFINES += -DWLAN_FEATURE_LFR_MBB
+endif
+
ifeq ($(CONFIG_PRIMA_WLAN_OKC),y)
CDEFINES += -DFEATURE_WLAN_OKC
endif
diff --git a/riva/inc/wlan_hal_msg.h b/riva/inc/wlan_hal_msg.h
index c91bb38..731d50a 100644
--- a/riva/inc/wlan_hal_msg.h
+++ b/riva/inc/wlan_hal_msg.h
@@ -842,6 +842,9 @@
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
eSIR_LINK_FT_PREASSOC_STATE = 16,
#endif
+#ifdef WLAN_FEATURE_LFR_MBB
+ eSIR_LINK_PRE_AUTH_REASSOC_STATE = 17,
+#endif
eSIR_LINK_MAX = WLAN_HAL_MAX_ENUM_SIZE
} tSirLinkState;
@@ -6904,6 +6907,7 @@
SAP_MODE_WOW = 64,
SAP_OFFLOADS = 65,
SAP_BUFF_ALLOC = 66,
+ MAKE_BEFORE_BREAK = 67,
NUD_DEBUG = 68,
MAX_FEATURE_SUPPORTED = 128,
} placeHolderInCapBitmap;