Переглянути джерело

qcacld-3.0: Optimize LFR3 roam synch propagation

The current roam sync propagation for LFR3.0 in the host driver is
based on queuing and message processing mechanism. This can lead
to many unknown sequence of operations as there might be other
messages sitting in the queue which may interrupt with this
operation. Hence, it would be good to introduce a callback mechanism
which take care of running the code to execution completely in case
of roam synch propagation.
It also improves to reduce the roam delay by 50 percent as compared
to the existing mechanism.

CRs-Fixed: 962290
Change-Id: I4af569b1e3020a64beb606e8bbffd7613775138f
Varun Reddy Yeturu 9 роки тому
батько
коміт
d5939f8b45

+ 10 - 1
core/hdd/inc/wlan_hdd_assoc.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -252,4 +252,13 @@ CDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
 				 uint8_t sta_id,
 				 enum ol_txrx_peer_state sta_state,
 				 bool roam_synch_in_progress);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo);
+#else
+static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
+{
+	return false;
+}
+#endif
+
 #endif

+ 18 - 20
core/hdd/src/wlan_hdd_assoc.c

@@ -730,8 +730,9 @@ static void hdd_send_association_event(struct net_device *dev,
 			return;
 		}
 
-		cds_incr_active_session(pAdapter->device_mode,
-						pAdapter->sessionId);
+		if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
+			cds_incr_active_session(pAdapter->device_mode,
+					pAdapter->sessionId);
 		memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
 		       sizeof(pCsrRoamInfo->pBssDesc->bssId));
 
@@ -1415,7 +1416,10 @@ static void hdd_send_re_assoc_event(struct net_device *dev,
 	 * active session count should still be the same and hence upon
 	 * successful reassoc decrement the active session count here.
 	 */
-	cds_decr_session_set_pcl(pAdapter->device_mode, pAdapter->sessionId);
+	if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
+		cds_decr_session_set_pcl(
+				pAdapter->device_mode,
+				pAdapter->sessionId);
 
 	/* Send the Assoc Resp, the supplicant needs this for initial Auth */
 	len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
@@ -1485,18 +1489,17 @@ done:
 
 /**
  * hdd_is_roam_sync_in_progress()- Check if roam offloaded
+ * @roaminfo - Roaming Information
  *
  * Return: roam sync status if roaming offloaded else false
  */
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
+bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
 {
-	return roaminfo->roamSynchInProgress;
-}
-#else
-static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
-{
-	return false;
+	if (roaminfo)
+		return roaminfo->roamSynchInProgress;
+	else
+		return false;
 }
 #endif
 
@@ -1724,13 +1727,6 @@ defined(WLAN_FEATURE_VOWIFI_11R)
 		return CDF_STATUS_E_FAILURE;
 	}
 
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	if (pRoamInfo && pRoamInfo->roamSynchInProgress) {
-		/* change logging before release */
-		hddLog(LOG3, "LFR3:hdd_association_completion_handler");
-	}
-#endif
-
 	/* HDD has initiated disconnect, do not send connect result indication
 	 * to kernel as it will be handled by __cfg80211_disconnect.
 	 */
@@ -1961,9 +1957,11 @@ defined(FEATURE_WLAN_LFR)
 						 * decrement the active session
 						 * count here.
 						 */
-						cds_decr_session_set_pcl
-							(pAdapter->device_mode,
-							pAdapter->sessionId);
+						if (!hdd_is_roam_sync_in_progress
+								(pRoamInfo))
+							cds_decr_session_set_pcl
+								(pAdapter->device_mode,
+								 pAdapter->sessionId);
 						hddLog(LOG1,
 						       FL("ft_carrier_on is %d, sending roamed indication"),
 						       ft_carrier_on);

+ 8 - 0
core/mac/inc/sir_api.h

@@ -162,6 +162,9 @@ typedef enum {
 #define SIR_UAPSD_FLAG_ACBK     (1 << SIR_UAPSD_BITOFFSET_ACBK)
 #define SIR_UAPSD_FLAG_ACBE     (1 << SIR_UAPSD_BITOFFSET_ACBE)
 #define SIR_UAPSD_GET(ac, mask)      (((mask) & (SIR_UAPSD_FLAG_ ## ac)) >> SIR_UAPSD_BITOFFSET_ ## ac)
+
+#define ROAM_SYNCH_PROPAGATION 1
+#define ROAMING_TX_QUEUE_DISABLE 2
 #endif
 
 /**
@@ -423,6 +426,8 @@ typedef struct sSirSmeReadyReq {
 	uint16_t length;
 	uint16_t transactionId;
 	void *add_bssdescr_cb;
+	void *csr_roam_synch_cb;
+	void *pe_roam_synch_cb;
 } tSirSmeReadyReq, *tpSirSmeReadyReq;
 
 /**
@@ -3953,6 +3958,9 @@ typedef struct sSirSmeRoamOffloadSynchInd {
 	uint8_t kck[SIR_KCK_KEY_LEN];
 	uint8_t kek[SIR_KEK_KEY_LEN];
 	uint8_t replay_ctr[SIR_REPLAY_CTR_LEN];
+	void *add_bss_params;
+	tpSirSmeJoinRsp join_rsp;
+	uint16_t aid;
 	tpSirBssDescription  bss_desc_ptr;
 } roam_offload_synch_ind;
 

+ 0 - 1
core/mac/inc/wni_api.h

@@ -213,7 +213,6 @@ enum eWniMsgTypes {
 	eWNI_SME_SET_HT_2040_MODE,
 #endif
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	eWNI_SME_ROAM_OFFLOAD_SYNCH_IND,        /* Roam Synch Indication from WMA to SME */
 	eWNI_SME_HO_FAIL_IND,   /* Hand Off Failure Ind from WMA to SME */
 #endif
 #ifdef WLAN_FEATURE_NAN

+ 11 - 2
core/mac/src/pe/include/lim_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -169,7 +169,9 @@ bool lim_is_deauth_diassoc_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info);
 bool lim_is_assoc_req_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info);
 #endif
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-void lim_roam_offload_synch_ind(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
+CDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
+	struct sSirSmeRoamOffloadSynchInd *roam_sync_ind_ptr,
+	tpSirBssDescription  bss_desc_ptr);
 #endif
 #define limGetQosMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limQosEnabled)
 #define limGetWmeMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWmeEnabled)
@@ -246,6 +248,13 @@ void lim_process_abort_scan_ind(tpAniSirGlobal pMac, uint8_t sessionId,
 	uint32_t scan_id);
 
 void __lim_process_sme_assoc_cnf_new(tpAniSirGlobal, uint32_t, uint32_t *);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+void lim_fill_join_rsp_ht_caps(tpPESession session, tpSirSmeJoinRsp rsp);
+#else
+static inline void lim_fill_join_rsp_ht_caps(tpPESession session,
+	tpSirSmeJoinRsp rsp)
+{}
+#endif
 
 /************************************************************/
 #endif /* __LIM_API_H */

+ 183 - 121
core/mac/src/pe/lim/lim_api.c

@@ -1076,10 +1076,11 @@ CDF_STATUS pe_handle_mgmt_frame(void *p_cds_gctx, void *cds_buff)
 /**
  * pe_register_wma_handle() - register management frame handler to WMA
  * @pMac: mac global ctx
+ * @ready_req: Ready request parameters
  *
  * Return: None
  */
-void pe_register_wma_handle(tpAniSirGlobal pMac)
+void pe_register_wma_handle(tpAniSirGlobal pMac, tSirSmeReadyReq *ready_req)
 {
 	void *p_cds_gctx;
 	CDF_STATUS retStatus;
@@ -1092,6 +1093,12 @@ void pe_register_wma_handle(tpAniSirGlobal pMac)
 		lim_log(pMac, LOGP,
 			FL("Registering the PE Handle with WMA has failed"));
 
+	retStatus = wma_register_roaming_callbacks(p_cds_gctx,
+			ready_req->csr_roam_synch_cb,
+			ready_req->pe_roam_synch_cb);
+	if (retStatus != CDF_STATUS_SUCCESS)
+		lim_log(pMac, LOGP,
+			FL("Registering roaming callbacks with WMA failed"));
 }
 
 /**
@@ -1791,15 +1798,54 @@ void lim_ps_offload_handle_missed_beacon_ind(tpAniSirGlobal pMac, tpSirMsgQ pMsg
 	return;
 }
 
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+/**
+ * lim_fill_join_rsp_ht_caps() - Fill the HT caps in join response
+ * @session: PE Session
+ * @join_rsp: Join response buffer to be filled up.
+ *
+ * Return: None
+ */
+void lim_fill_join_rsp_ht_caps(tpPESession session, tpSirSmeJoinRsp join_rsp)
+{
+	tSirSmeHTProfile *ht_profile;
+	if (session == NULL) {
+		lim_log(mac_ctx, LOGE, FL("Invalid Session"));
+		return;
+	}
+	if (join_rsp == NULL) {
+		lim_log(mac_ctx, LOGE, FL("Invalid Join Response"));
+		return;
+	}
+	if (session->cc_switch_mode !=
+			CDF_MCC_TO_SCC_SWITCH_DISABLE) {
+		ht_profile = &join_rsp->HTProfile;
+		ht_profile->htSupportedChannelWidthSet =
+			session->htSupportedChannelWidthSet;
+		ht_profile->htRecommendedTxWidthSet =
+			session->htRecommendedTxWidthSet;
+		ht_profile->htSecondaryChannelOffset =
+			session->htSecondaryChannelOffset;
+		ht_profile->dot11mode = session->dot11mode;
+		ht_profile->htCapability = session->htCapability;
+	}
+	ht_profile->vhtCapability = session->vhtCapability;
+	ht_profile->vhtTxChannelWidthSet =
+		session->vhtTxChannelWidthSet;
+	ht_profile->apCenterChan = session->ch_center_freq_seg0;
+	ht_profile->apChanWidth = session->ch_width;
+}
+#endif
+
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 CDF_STATUS lim_roam_fill_bss_descr(tpAniSirGlobal pMac,
-		roam_offload_synch_ind *roam_offload_synch_ind_ptr)
+		roam_offload_synch_ind *roam_offload_synch_ind_ptr,
+		tpSirBssDescription  bss_desc_ptr)
 {
 	uint32_t ie_len = 0;
 	tpSirProbeRespBeacon parsed_frm_ptr;
 	tpSirMacMgmtHdr mac_hdr;
 	uint8_t *bcn_proberesp_ptr;
-	tSirBssDescription *bss_desc_ptr = NULL;
 
 	bcn_proberesp_ptr = (uint8_t *)roam_offload_synch_ind_ptr +
 		roam_offload_synch_ind_ptr->beaconProbeRespOffset;
@@ -1821,7 +1867,7 @@ CDF_STATUS lim_roam_fill_bss_descr(tpAniSirGlobal pMac,
 	}
 
 	CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
-		"LFR3: Beacon/Prb Rsp:");
+		"LFR3:Beacon/Prb Rsp:%d", roam_offload_synch_ind_ptr->isBeacon);
 	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
 	bcn_proberesp_ptr, roam_offload_synch_ind_ptr->beaconProbeRespLength);
 	if (roam_offload_synch_ind_ptr->isBeacon) {
@@ -1856,20 +1902,6 @@ CDF_STATUS lim_roam_fill_bss_descr(tpAniSirGlobal pMac,
 		ie_len = roam_offload_synch_ind_ptr->beaconProbeRespLength -
 			(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
 	}
-	/*
-	 * Memory allocated below is freed up in csrProcessRoamOffloadSynchInd
-	 */
-	roam_offload_synch_ind_ptr->bss_desc_ptr =
-		cdf_mem_malloc(sizeof (tSirBssDescription) + ie_len);
-	bss_desc_ptr = roam_offload_synch_ind_ptr->bss_desc_ptr;
-	if (NULL == bss_desc_ptr) {
-		CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-				"LFR3:Failed to allocate memory");
-		CDF_ASSERT(bss_desc_ptr != NULL);
-		return CDF_STATUS_E_NOMEM;
-	}
-	cdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription));
-
 	/*
 	 * Length of BSS desription is without length of
 	 * length itself and length of pointer
@@ -1955,129 +1987,159 @@ CDF_STATUS lim_roam_fill_bss_descr(tpAniSirGlobal pMac,
 	cdf_mem_free(parsed_frm_ptr);
 	return CDF_STATUS_SUCCESS;
 }
-
-/**-----------------------------------------------------------------
-  * brief lim_roam_offload_synch_ind() - Handles Roam Synch Indication
-  * param pMac - global mac structure
-  * return - none
-  *-----------------------------------------------------------------
-  **/
-void lim_roam_offload_synch_ind(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+/**
+ * pe_roam_synch_callback() - PE level callback for roam synch propagation
+ * @mac_ctx: MAC Context
+ * @roam_sync_ind_ptr: Roam synch indication buffer pointer
+ * @bss_desc: BSS Descriptor pointer
+ *
+ * This is a PE level callback called from WMA to complete the roam synch
+ * propagation at PE level and also fill the BSS descriptor which will be
+ * helpful further to complete the roam synch propagation.
+ *
+ * Return: Success or Failure status
+ */
+CDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
+	roam_offload_synch_ind *roam_sync_ind_ptr,
+	tpSirBssDescription  bss_desc)
 {
 	tpPESession session_ptr;
 	tpPESession ft_session_ptr;
 	uint8_t session_id;
-	tSirMsgQ mmh_msg;
-	tSirBssDescription *bss_desc_ptr = NULL;
-	roam_offload_synch_ind *roam_sync_ind_ptr =
-		(roam_offload_synch_ind *)pMsg->bodyptr;
+	tpDphHashNode curr_sta_ds;
+	uint16_t aid;
+	tpAddBssParams add_bss_params;
+	uint8_t local_nss;
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
 
 	if (!roam_sync_ind_ptr) {
-		CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-				"LFR3:%s:roam_sync_ind_ptr is NULL", __func__);
-		return;
+		lim_log(mac_ctx, LOGE, FL("LFR3:roam_sync_ind_ptr is NULL"));
+		return status;
 	}
-	CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-			"LFR3: Received WMA_ROAM_OFFLOAD_SYNCH_IND");
-	CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
-			"LFR3:%s:authStatus=%d, vdevId=%d", __func__,
-			roam_sync_ind_ptr->authStatus,
-			roam_sync_ind_ptr->roamedVdevId);
-	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
-			roam_sync_ind_ptr->bssid.bytes, CDF_MAC_ADDR_SIZE);
-	session_ptr = pe_find_session_by_bss_idx(pMac,
-			roam_sync_ind_ptr->roamedVdevId);
+	lim_log(mac_ctx, LOGE, FL("LFR3:Received WMA_ROAM_OFFLOAD_SYNCH_IND"));
+	lim_log(mac_ctx, CDF_TRACE_LEVEL_DEBUG, FL("LFR3:auth=%d, vdevId=%d"),
+		roam_sync_ind_ptr->authStatus, roam_sync_ind_ptr->roamedVdevId);
+	lim_print_mac_addr(mac_ctx, roam_sync_ind_ptr->bssid.bytes,
+			CDF_TRACE_LEVEL_DEBUG);
+	session_ptr = pe_find_session_by_sme_session_id(mac_ctx,
+				roam_sync_ind_ptr->roamedVdevId);
 	if (session_ptr == NULL) {
-		CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-			"%s: LFR3:Unable to find session", __func__);
-		return;
+		lim_log(mac_ctx, LOGE, FL("LFR3:Unable to find session"));
+		return status;
 	}
-	/* Nothing to be done if the session is not in STA mode */
 	if (!LIM_IS_STA_ROLE(session_ptr)) {
-		CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-				"session is not in STA mode");
-		return;
+		lim_log(mac_ctx, LOGE, FL("LFR3:session is not in STA mode"));
+		return status;
 	}
-	if (!CDF_IS_STATUS_SUCCESS(lim_roam_fill_bss_descr(pMac,
-					roam_sync_ind_ptr))) {
-		CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-				"LFR3:%s:Failed to fill Bss Descr", __func__);
-		return;
+	status = lim_roam_fill_bss_descr(mac_ctx, roam_sync_ind_ptr, bss_desc);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		lim_log(mac_ctx, LOGE, FL("LFR3:Failed to fill Bss Descr"));
+		return status;
 	}
-	bss_desc_ptr = roam_sync_ind_ptr->bss_desc_ptr;
-	ft_session_ptr = pe_create_session(pMac, bss_desc_ptr->bssId,
-				&session_id, pMac->lim.maxStation,
-				eSIR_INFRASTRUCTURE_MODE);
+	status = CDF_STATUS_E_FAILURE;
+	ft_session_ptr = pe_create_session(mac_ctx, bss_desc->bssId,
+			&session_id, mac_ctx->lim.maxStation,
+			eSIR_INFRASTRUCTURE_MODE);
 	if (ft_session_ptr == NULL) {
-		CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-		"LFR3: Session Can't be created for new AP during Roam Synch");
-		lim_print_mac_addr(pMac, bss_desc_ptr->bssId, LOGE);
-		return;
+		lim_log(mac_ctx, LOGE, FL("LFR3:Cannot create PE Session"));
+		lim_print_mac_addr(mac_ctx, bss_desc->bssId, LOGE);
+		return status;
 	}
 	ft_session_ptr->peSessionId = session_id;
 	sir_copy_mac_addr(ft_session_ptr->selfMacAddr, session_ptr->selfMacAddr);
-	sir_copy_mac_addr(ft_session_ptr->limReAssocbssId, bss_desc_ptr->bssId);
+	sir_copy_mac_addr(ft_session_ptr->limReAssocbssId, bss_desc->bssId);
 	ft_session_ptr->bssType = eSIR_INFRASTRUCTURE_MODE;
-	/**
-	 * Set bRoamSynchInProgress here since this session is
-	 *specific to roam synch indication. This flag will
-	 *later be used to differentiate LFR3 with LFR2 in LIM
-	 **/
+	session_ptr->bRoamSynchInProgress = true;
 	ft_session_ptr->bRoamSynchInProgress = true;
-
-	if (ft_session_ptr->bssType == eSIR_INFRASTRUCTURE_MODE) {
-		ft_session_ptr->limSystemRole = eLIM_STA_ROLE;
-	} else {
-		CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-		"LFR3:Invalid bss type");
-		return;
+	ft_session_ptr->limSystemRole = eLIM_STA_ROLE;
+	sir_copy_mac_addr(session_ptr->limReAssocbssId, bss_desc->bssId);
+	ft_session_ptr->csaOffloadEnable = session_ptr->csaOffloadEnable;
+
+	lim_fill_ft_session(mac_ctx, bss_desc, ft_session_ptr, session_ptr);
+	lim_ft_prepare_add_bss_req(mac_ctx, false, ft_session_ptr, bss_desc);
+	roam_sync_ind_ptr->add_bss_params =
+		(tpAddBssParams) ft_session_ptr->ftPEContext.pAddBssReq;
+	add_bss_params = ft_session_ptr->ftPEContext.pAddBssReq;
+	lim_delete_tdls_peers(mac_ctx, session_ptr);
+	curr_sta_ds = dph_lookup_hash_entry(mac_ctx, session_ptr->bssId,
+			&aid, &session_ptr->dph.dphHashTable);
+	local_nss = curr_sta_ds->nss;
+	session_ptr->limSmeState = eLIM_SME_IDLE_STATE;
+	lim_cleanup_rx_path(mac_ctx, curr_sta_ds, session_ptr);
+	lim_delete_dph_hash_entry(mac_ctx, curr_sta_ds->staAddr,
+			aid, session_ptr);
+	pe_delete_session(mac_ctx, session_ptr);
+	session_ptr = NULL;
+	ft_session_ptr->nss = local_nss;
+	curr_sta_ds = dph_add_hash_entry(mac_ctx,
+			roam_sync_ind_ptr->bssid.bytes, DPH_STA_HASH_INDEX_PEER,
+			&ft_session_ptr->dph.dphHashTable);
+	if (curr_sta_ds == NULL) {
+		lim_log(mac_ctx, LOGE, FL("LFR3:failed to add hash entry for"));
+		lim_print_mac_addr(mac_ctx,
+				add_bss_params->staContext.staMac, LOGE);
+		ft_session_ptr->bRoamSynchInProgress = false;
+		return status;
 	}
-	ft_session_ptr->limPrevSmeState = ft_session_ptr->limSmeState;
-	ft_session_ptr->limSmeState = eLIM_SME_WT_REASSOC_STATE;
-	CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
-			"LFR3:%s:created session (%p) with id = %d",
-			__func__, ft_session_ptr, ft_session_ptr->peSessionId);
-	/* Update the ReAssoc BSSID of the current session */
-	sir_copy_mac_addr(session_ptr->limReAssocbssId, bss_desc_ptr->bssId);
-	lim_print_mac_addr(pMac, session_ptr->limReAssocbssId, LOG2);
-
-	/* Prepare the session right now with as much as possible */
-	lim_fill_ft_session(pMac, bss_desc_ptr, ft_session_ptr, session_ptr);
-
-	if (roam_sync_ind_ptr->reassoc_req_length) {
-		/*
-		 * For LFR3 the Assoc Request frame was sent by firmware, hence
-		 * pe session struct does not have corresponding IEs. Firmware
-		 * sends whole ASSOC req frame upto host in Roam Sync Event.
-		 * Copy this frame pe session's buffer, so that it can follow
-		 * LFR2 code path to send them to supplicant.
-		 */
-		ft_session_ptr->assocReqLen =
-			roam_sync_ind_ptr->reassoc_req_length
-			- SIR_MAC_HDR_LEN_3A - SIR_MAC_REASSOC_SSID_OFFSET;
-		ft_session_ptr->assocReq =
-			cdf_mem_malloc(ft_session_ptr->assocReqLen);
-		if (NULL == ft_session_ptr->assocReq) {
-			CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
-				"LFR3: Failed to alloc memory for Assoc Req");
-			return;
-		}
-		cdf_mem_copy(ft_session_ptr->assocReq,
-			     (uint8_t *)roam_sync_ind_ptr +
-			     roam_sync_ind_ptr->reassoc_req_offset +
-			     SIR_MAC_HDR_LEN_3A + SIR_MAC_REASSOC_SSID_OFFSET,
-			     ft_session_ptr->assocReqLen);
-	}
-	lim_ft_prepare_add_bss_req(pMac, false, ft_session_ptr, bss_desc_ptr);
-	mmh_msg.type =
-		roam_sync_ind_ptr->messageType;
-	/* eWNI_SME_ROAM_OFFLOAD_SYNCH_IND */
-	mmh_msg.bodyptr = roam_sync_ind_ptr;
-	mmh_msg.bodyval = 0;
+	ft_session_ptr->bssIdx = (uint8_t) add_bss_params->bssIdx;
+
+	curr_sta_ds->bssId = add_bss_params->bssIdx;
+	curr_sta_ds->staIndex =
+		add_bss_params->staContext.staIdx;
+	curr_sta_ds->ucUcastSig =
+		add_bss_params->staContext.ucUcastSig;
+	curr_sta_ds->ucBcastSig =
+		add_bss_params->staContext.ucBcastSig;
+	rrm_cache_mgmt_tx_power(mac_ctx,
+		add_bss_params->txMgmtPower, ft_session_ptr);
+	mac_ctx->roam.reassocRespLen = roam_sync_ind_ptr->reassocRespLength;
+	mac_ctx->roam.pReassocResp =
+		cdf_mem_malloc(mac_ctx->roam.reassocRespLen);
+	if (NULL == mac_ctx->roam.pReassocResp) {
+		lim_log(mac_ctx, LOGE, FL("LFR3:assoc resp mem alloc failed"));
+		ft_session_ptr->bRoamSynchInProgress = false;
+		return CDF_STATUS_E_NOMEM;
+	}
+	cdf_mem_copy(mac_ctx->roam.pReassocResp,
+			(uint8_t *)roam_sync_ind_ptr +
+			roam_sync_ind_ptr->reassocRespOffset,
+			mac_ctx->roam.reassocRespLen);
 
-	CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
-		"LFR3:%s:sending eWNI_SME_ROAM_OFFLOAD_SYNCH_IND", __func__);
-	lim_sys_process_mmh_msg_api(pMac, &mmh_msg,  ePROT);
+	lim_log(mac_ctx, LOG1, FL("LFR3:the reassoc resp frame data:"));
+	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
+			mac_ctx->roam.pReassocResp,
+			mac_ctx->roam.reassocRespLen);
+	ft_session_ptr->bRoamSynchInProgress = true;
+	lim_process_assoc_rsp_frame(mac_ctx, mac_ctx->roam.pReassocResp,
+			LIM_REASSOC, ft_session_ptr);
+	roam_sync_ind_ptr->aid = ft_session_ptr->limAID;
+	curr_sta_ds->mlmStaContext.mlmState =
+		eLIM_MLM_LINK_ESTABLISHED_STATE;
+	curr_sta_ds->nss = local_nss;
+	ft_session_ptr->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+	lim_init_tdls_data(mac_ctx, ft_session_ptr);
+	roam_sync_ind_ptr->join_rsp->vht_channel_width =
+		ft_session_ptr->ch_width;
+	roam_sync_ind_ptr->join_rsp->staId = curr_sta_ds->staIndex;
+	roam_sync_ind_ptr->join_rsp->ucastSig = curr_sta_ds->ucUcastSig;
+	roam_sync_ind_ptr->join_rsp->bcastSig = curr_sta_ds->ucBcastSig;
+	roam_sync_ind_ptr->join_rsp->timingMeasCap = curr_sta_ds->timingMeasCap;
+	roam_sync_ind_ptr->join_rsp->nss = curr_sta_ds->nss;
+	roam_sync_ind_ptr->join_rsp->max_rate_flags =
+		lim_get_max_rate_flags(mac_ctx, curr_sta_ds);
+	roam_sync_ind_ptr->join_rsp->tdls_prohibited =
+		ft_session_ptr->tdls_prohibited;
+	roam_sync_ind_ptr->join_rsp->tdls_chan_swit_prohibited =
+		ft_session_ptr->tdls_chan_swit_prohibited;
+	roam_sync_ind_ptr->join_rsp->aid = ft_session_ptr->limAID;
+	lim_fill_join_rsp_ht_caps(ft_session_ptr, roam_sync_ind_ptr->join_rsp);
+	ft_session_ptr->limPrevSmeState = ft_session_ptr->limSmeState;
+	ft_session_ptr->limSmeState = eLIM_SME_LINK_EST_STATE;
+	ft_session_ptr->bRoamSynchInProgress = false;
+	if (mac_ctx->roam.pReassocResp)
+		cdf_mem_free(mac_ctx->roam.pReassocResp);
+	mac_ctx->roam.pReassocResp = NULL;
+	return CDF_STATUS_SUCCESS;
 }
 #endif
 

+ 5 - 6
core/mac/src/pe/lim/lim_assoc_utils.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -646,6 +646,10 @@ lim_cleanup_rx_path(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
 	 * releases those BDs
 	 */
 	pStaDs->valid = 0;
+	lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
+	/* Any roaming related changes should be above this line */
+	if (psessionEntry->bRoamSynchInProgress)
+		return eSIR_SUCCESS;
 	pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
 
 	if (LIM_IS_STA_ROLE(psessionEntry) ||
@@ -660,11 +664,6 @@ lim_cleanup_rx_path(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
 		pMac->lim.gLastBeaconDtimCount = 0;
 		pMac->lim.gLastBeaconDtimPeriod = 0;
 
-#ifdef FEATURE_WLAN_ESE
-#ifdef FEATURE_WLAN_ESE_UPLOAD
-		lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
-#endif /* FEATURE_WLAN_ESE_UPLOAD */
-#endif
 
 	}
 #ifdef WLAN_DEBUG

+ 6 - 1
core/mac/src/pe/lim/lim_assoc_utils.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -207,6 +207,11 @@ void lim_send_sme_unprotected_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameT
 #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
 void lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
 			     uint8_t tid, uint8_t state, uint16_t measInterval);
+#else
+static inline void lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac,
+	tpPESession psessionEntry, uint8_t tid,
+	uint8_t state, uint16_t measInterval)
+{}
 #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
 
 #endif /* __LIM_ASSOC_UTILS_H */

+ 17 - 13
core/mac/src/pe/lim/lim_ft.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -813,11 +813,14 @@ tSirRetStatus lim_ft_prepare_add_bss_req(tpAniSirGlobal pMac,
 	pAddBssParams->sessionId = pftSessionEntry->peSessionId;
 
 	/* Set a new state for MLME */
-
-	pftSessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE;
-	MTRACE(mac_trace
-		       (pMac, TRACE_CODE_MLM_STATE, pftSessionEntry->peSessionId,
-		       eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE));
+	if (!pftSessionEntry->bRoamSynchInProgress) {
+		pftSessionEntry->limMlmState =
+			eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE;
+		MTRACE(mac_trace
+			(pMac, TRACE_CODE_MLM_STATE,
+			pftSessionEntry->peSessionId,
+			eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE));
+	}
 	pAddBssParams->halPersona = (uint8_t) pftSessionEntry->pePersona;
 
 	pftSessionEntry->ftPEContext.pAddBssReq = pAddBssParams;
@@ -1040,13 +1043,14 @@ void lim_fill_ft_session(tpAniSirGlobal pMac,
 		regMax, localPowerConstraint, pMac->roam.configParam.nTxPowerCap,
 		pftSessionEntry->maxTxPower);
 #endif
-
-	pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
-	pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
-	MTRACE(mac_trace
-		       (pMac, TRACE_CODE_SME_STATE, pftSessionEntry->peSessionId,
-		       pftSessionEntry->limSmeState));
-
+	if (!psessionEntry->bRoamSynchInProgress) {
+		pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
+		pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+		MTRACE(mac_trace(pMac,
+				TRACE_CODE_SME_STATE,
+				pftSessionEntry->peSessionId,
+				pftSessionEntry->limSmeState));
+	}
 	pftSessionEntry->encryptType = psessionEntry->encryptType;
 #ifdef WLAN_FEATURE_11W
 	pftSessionEntry->limRmfEnabled = psessionEntry->limRmfEnabled;

+ 9 - 6
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -646,6 +646,7 @@ lim_process_assoc_rsp_frame(tpAniSirGlobal mac_ctx,
 	if (((subtype == LIM_ASSOC) &&
 		(session_entry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE)) ||
 		((subtype == LIM_REASSOC) &&
+		 !session_entry->bRoamSynchInProgress &&
 		((session_entry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE)
 #if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 		&& (session_entry->limMlmState !=
@@ -917,7 +918,8 @@ lim_process_assoc_rsp_frame(tpAniSirGlobal mac_ctx,
 #endif
 	if (!((session_entry->bssType == eSIR_BTAMP_STA_MODE) ||
 		((session_entry->bssType == eSIR_BTAMP_AP_MODE) &&
-		LIM_IS_BT_AMP_STA_ROLE(session_entry)))) {
+		LIM_IS_BT_AMP_STA_ROLE(session_entry)) ||
+		session_entry->bRoamSynchInProgress)) {
 		if (lim_set_link_state
 			(mac_ctx, eSIR_LINK_POSTASSOC_STATE,
 			session_entry->bssId,
@@ -972,8 +974,9 @@ lim_process_assoc_rsp_frame(tpAniSirGlobal mac_ctx,
 			goto assocReject;
 		}
 #if defined(WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
-		if (session_entry->limMlmState ==
-		    eLIM_MLM_WT_FT_REASSOC_RSP_STATE) {
+		if ((session_entry->limMlmState ==
+		    eLIM_MLM_WT_FT_REASSOC_RSP_STATE) ||
+			session_entry->bRoamSynchInProgress) {
 #ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
 			lim_log(mac_ctx, LOG1, FL("Sending self sta"));
 #endif
@@ -992,11 +995,11 @@ lim_process_assoc_rsp_frame(tpAniSirGlobal mac_ctx,
 			lim_send_edca_params(mac_ctx,
 				session_entry->gLimEdcaParamsActive,
 				sta_ds->bssId);
+			lim_add_ft_sta_self(mac_ctx, (assoc_rsp->aid & 0x3FFF),
+				session_entry);
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 		}
 #endif
-			lim_add_ft_sta_self(mac_ctx, (assoc_rsp->aid & 0x3FFF),
-				session_entry);
 			cdf_mem_free(beacon);
 			return;
 		}

+ 0 - 7
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -1503,13 +1503,6 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
 		cdf_mem_free(msg->bodyptr);
 		msg->bodyptr = NULL;
 		break;
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	case WMA_ROAM_OFFLOAD_SYNCH_IND:
-		lim_roam_offload_synch_ind(mac_ctx, msg);
-		/* bodyPtr is freed after handling
-		 * eWNI_SME_ROAM_OFFLOAD_SYNCH_IND in sme_ProcessMsg */
-		break;
-#endif
 	case SIR_LIM_ADDTS_RSP_TIMEOUT:
 		lim_process_sme_req_messages(mac_ctx, msg);
 		break;

+ 4 - 2
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -113,7 +113,8 @@ static void lim_process_modify_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg);
 
 static void lim_process_update_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg);
 
-extern void pe_register_wma_handle(tpAniSirGlobal pMac);
+extern void pe_register_wma_handle(tpAniSirGlobal pMac,
+		tSirSmeReadyReq *ready_req);
 
 static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx,
 						uint32_t *msg);
@@ -483,7 +484,8 @@ static bool __lim_process_sme_sys_ready_ind(tpAniSirGlobal pMac, uint32_t *pMsgB
 	msg.bodyval = 0;
 
 	if (ANI_DRIVER_TYPE(pMac) != eDRIVER_TYPE_MFG) {
-		pe_register_wma_handle(pMac);
+		ready_req->pe_roam_synch_cb = pe_roam_synch_callback;
+		pe_register_wma_handle(pMac, ready_req);
 		pMac->lim.add_bssdescr_callback = ready_req->add_bssdescr_cb;
 	}
 	PELOGW(lim_log(pMac, LOGW, FL("sending WMA_SYS_READY_IND msg to HAL"));)

+ 3 - 1
core/mac/src/pe/lim/lim_process_tdls.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -3272,6 +3272,8 @@ tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
 			CLEAR_BIT(session_entry->peerAIDBitmap[i], aid);
 		}
 	}
+	if (session_entry->bRoamSynchInProgress)
+		return eSIR_SUCCESS;
 	lim_send_sme_tdls_delete_all_peer_ind(mac_ctx, session_entry);
 
 	return eSIR_SUCCESS;

+ 0 - 4
core/mac/src/sys/legacy/src/utils/src/mac_trace.c

@@ -327,9 +327,6 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
 		CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
 		CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_REQ);
 		CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_RSP);
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-		CASE_RETURN_STRING(eWNI_SME_ROAM_OFFLOAD_SYNCH_IND);
-#endif
 		CASE_RETURN_STRING(eWNI_SME_SET_HW_MODE_REQ);
 		CASE_RETURN_STRING(eWNI_SME_SET_HW_MODE_RESP);
 		CASE_RETURN_STRING(eWNI_SME_HW_MODE_TRANS_IND);
@@ -506,7 +503,6 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg)
 		CASE_RETURN_STRING(WMA_SET_THERMAL_LEVEL);
 		CASE_RETURN_STRING(WMA_SET_SAP_INTRABSS_DIS);
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-		CASE_RETURN_STRING(WMA_ROAM_OFFLOAD_SYNCH_CNF);
 		CASE_RETURN_STRING(WMA_ROAM_OFFLOAD_SYNCH_FAIL);
 #endif
 		CASE_RETURN_STRING(SIR_HAL_SET_BASE_MACADDR_IND);

+ 8 - 0
core/sme/inc/csr_api.h

@@ -1607,4 +1607,12 @@ CDF_STATUS csr_roam_issue_ft_roam_offload_synch(tHalHandle hHal,
 		uint32_t sessionId, tSirBssDescription *pBssDescription);
 #endif
 typedef void (*tCsrLinkStatusCallback)(uint8_t status, void *pContext);
+#ifdef FEATURE_WLAN_TDLS
+void csr_roam_fill_tdls_info(tCsrRoamInfo *roam_info, tpSirSmeJoinRsp join_rsp);
+#else
+static inline void csr_roam_fill_tdls_info(tCsrRoamInfo *roam_info,
+		tpSirSmeJoinRsp join_rsp)
+{}
+#endif
+
 #endif

+ 5 - 5
core/sme/inc/csr_internal.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -847,7 +847,6 @@ typedef struct tagCsrRoamOffloadSynchStruct {
 	uint16_t chainMask;     /* chainmask */
 	uint16_t smpsMode;      /* smps.mode */
 	struct cdf_mac_addr bssid;      /* MAC address of roamed AP */
-	bool bRoamSynchInProgress;              /* a roam offload synch */
 	tCsrRoamOffloadAuthStatus authStatus;   /* auth status */
 	uint8_t kck[SIR_KCK_KEY_LEN];
 	uint8_t kek[SIR_KEK_KEY_LEN];
@@ -968,6 +967,7 @@ typedef struct tagCsrRoamSession {
 	uint8_t psk_pmk[SIR_ROAM_SCAN_PSK_SIZE];
 	size_t pmk_len;
 	uint8_t RoamKeyMgmtOffloadEnabled;
+	roam_offload_synch_ind *roam_synch_data;
 #endif
 #if defined WLAN_FEATURE_VOWIFI_11R
 	tftSMEContext ftSmeContext;
@@ -976,6 +976,7 @@ typedef struct tagCsrRoamSession {
 	uint8_t join_bssid_count;
 	struct csr_roam_stored_profile stored_roam_profile;
 	bool ch_switch_in_progress;
+	bool roam_synch_in_progress;
 } tCsrRoamSession;
 
 typedef struct tagCsrRoamStruct {
@@ -1359,10 +1360,9 @@ static inline void csr_roaming_report_diag_event(tpAniSirGlobal mac_ctx,
 {}
 #endif
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-void csr_process_roam_offload_synch_ind(tHalHandle hHal,
-		roam_offload_synch_ind * roam_synch_ind_ptr);
 CDF_STATUS csr_scan_save_roam_offload_ap_to_scan_cache(tpAniSirGlobal pMac,
-		roam_offload_synch_ind *roam_synch_ind_ptr);
+		roam_offload_synch_ind *roam_synch_ind_ptr,
+		tpSirBssDescription  bss_desc_ptr);
 void csr_process_ho_fail_ind(tpAniSirGlobal pMac, void *pMsgBuf);
 #endif
 bool csr_store_joinreq_param(tpAniSirGlobal mac_ctx,

+ 4 - 3
core/sme/inc/csr_neighbor_roam.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -297,9 +297,10 @@ CDF_STATUS csr_roam_read_tsf(tpAniSirGlobal pMac, uint8_t *pTimestamp,
 		const uint8_t sessionId);
 #endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-CDF_STATUS csr_roam_offload_send_synch_cnf(tpAniSirGlobal pMac,
-		uint8_t sessionId);
 CDF_STATUS csr_neighbor_roam_offload_update_preauth_list(tpAniSirGlobal pMac,
 		roam_offload_synch_ind *roam_synch_ind_ptr, uint8_t sessionId);
+void csr_roam_synch_callback(tpAniSirGlobal mac,
+	roam_offload_synch_ind *roam_synch_data,
+	tpSirBssDescription  bss_desc_ptr, uint8_t reason);
 #endif
 #endif /* CSR_NEIGHBOR_ROAM_H */

+ 1 - 5
core/sme/src/common/sme_api.c

@@ -1694,6 +1694,7 @@ CDF_STATUS sme_hdd_ready_ind(tHalHandle hHal)
 		Msg.messageType = eWNI_SME_SYS_READY_IND;
 		Msg.length = sizeof(tSirSmeReadyReq);
 		Msg.add_bssdescr_cb = csr_scan_process_single_bssdescr;
+		Msg.csr_roam_synch_cb = csr_roam_synch_callback;
 
 
 		if (eSIR_FAILURE != u_mac_post_ctrl_msg(hHal, (tSirMbMsg *) &Msg)) {
@@ -2242,11 +2243,6 @@ CDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg)
 	}
 	switch (pMsg->type) {
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	case eWNI_SME_ROAM_OFFLOAD_SYNCH_IND:
-		csr_process_roam_offload_synch_ind(pMac,
-				(roam_offload_synch_ind *) pMsg->bodyptr);
-		cdf_mem_free(pMsg->bodyptr);
-		break;
 	case eWNI_SME_HO_FAIL_IND:
 		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
 			  FL("LFR3: Rcvd eWNI_SME_HO_FAIL_IND"));

+ 330 - 193
core/sme/src/csr/csr_api_roam.c

@@ -4106,7 +4106,7 @@ void csr_roam_ccm_cfg_set_callback(tpAniSirGlobal pMac, int32_t result)
 	sessionId = pCommand->sessionId;
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	pSession = &pMac->roam.roamSession[sessionId];
-	if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
+	if (pSession->roam_synch_in_progress) {
 		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
 			  "LFR3:csr_roam_cfg_set_callback");
 	}
@@ -4160,6 +4160,8 @@ CDF_STATUS csr_roam_set_bss_config_cfg(tpAniSirGlobal pMac, uint32_t sessionId,
 	tSirRetStatus status;
 	uint32_t cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
 	uint8_t channel = 0;
+	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
+
 	/* Make sure we have the domain info for the BSS we try to connect to. */
 	/* Do we need to worry about sequence for OSs that are not Windows?? */
 	if (pBssDesc) {
@@ -4223,12 +4225,15 @@ CDF_STATUS csr_roam_set_bss_config_cfg(tpAniSirGlobal pMac, uint32_t sessionId,
 	} else {
 		csr_set_cfg_rate_set_from_profile(pMac, pProfile);
 	}
+	status = cfg_set_int(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
+			pBssConfig->uJoinTimeOut);
+	/* Any roaming related changes should be above this line */
+	if (pSession && pSession->roam_synch_in_progress)
+		return CDF_STATUS_SUCCESS;
 	/* Make this the last CFG to set. The callback will trigger a join_req */
 	/* Join time out */
 	csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_CONFIG, sessionId);
 
-	status = cfg_set_int(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
-			pBssConfig->uJoinTimeOut);
 	csr_roam_ccm_cfg_set_callback(pMac, status);
 	return CDF_STATUS_SUCCESS;
 }
@@ -5458,12 +5463,6 @@ static CDF_STATUS csr_roam_save_security_rsp_ie(tpAniSirGlobal pMac,
 		sms_log(pMac, LOGE, FL("session %d not found"), sessionId);
 		return CDF_STATUS_E_FAILURE;
 	}
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
-		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
-				FL("LFR3:csr_roam_save_security_rsp_ie"));
-	}
-#endif
 
 	if ((eCSR_AUTH_TYPE_WPA == authType) ||
 		(eCSR_AUTH_TYPE_WPA_PSK == authType) ||
@@ -5605,43 +5604,6 @@ eCsrPhyMode csr_roamdot11mode_to_phymode(uint8_t dot11mode)
 #endif
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-CDF_STATUS csr_roam_offload_send_synch_cnf(tpAniSirGlobal pMac, uint8_t sessionId)
-{
-	tpSirSmeRoamOffloadSynchCnf pRoamOffloadSynchCnf;
-	cds_msg_t msg;
-	tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
-	pRoamOffloadSynchCnf =
-		cdf_mem_malloc(sizeof(tSirSmeRoamOffloadSynchCnf));
-	if (NULL == pRoamOffloadSynchCnf) {
-		CDF_TRACE(CDF_MODULE_ID_SME,
-			  CDF_TRACE_LEVEL_ERROR,
-			  "%s: not able to allocate memory for roam"
-			  "offload synch confirmation data", __func__);
-		pSession->roamOffloadSynchParams.bRoamSynchInProgress =
-			false;
-		return CDF_STATUS_E_NOMEM;
-	}
-	pRoamOffloadSynchCnf->sessionId = sessionId;
-	msg.type = WMA_ROAM_OFFLOAD_SYNCH_CNF;
-	msg.reserved = 0;
-	msg.bodyptr = pRoamOffloadSynchCnf;
-	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
-		  "LFR3: Posting WMA_ROAM_OFFLOAD_SYNCH_CNF");
-	if (!CDF_IS_STATUS_SUCCESS
-		    (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
-		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
-			  "%s: Not able to post WMA_ROAM_OFFLOAD_SYNCH_CNF message to WMA",
-			  __func__);
-		cdf_mem_free(pRoamOffloadSynchCnf);
-		pSession->roamOffloadSynchParams.bRoamSynchInProgress =
-			false;
-		return CDF_STATUS_E_FAILURE;
-	}
-	csr_roaming_report_diag_event(pMac, NULL, eCSR_REASON_ROAM_SYNCH_CNF);
-	pSession->roamOffloadSynchParams.bRoamSynchInProgress = false;
-	return CDF_STATUS_SUCCESS;
-}
-
 void csr_roam_synch_clean_up (tpAniSirGlobal mac, uint8_t session_id)
 {
 	cds_msg_t msg;
@@ -5651,7 +5613,7 @@ void csr_roam_synch_clean_up (tpAniSirGlobal mac, uint8_t session_id)
 	/* Clean up the roam synch in progress for LFR3 */
 	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
 		  "%s: Roam Synch Failed, Clean Up", __func__);
-	session->roamOffloadSynchParams.bRoamSynchInProgress = false;
+	session->roam_synch_in_progress = false;
 
 	roam_offload_failed = cdf_mem_malloc(
 				sizeof(struct roam_offload_synch_fail));
@@ -6254,7 +6216,7 @@ static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx,
 				eSIR_TX_RX, 0, 0, NULL, 0);
 		} else {
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-			if (roam_offload_params->bRoamSynchInProgress
+			if (session->roam_synch_in_progress
 				&& (roam_offload_params->authStatus
 				== CSR_ROAM_AUTH_STATUS_AUTHENTICATED)) {
 				CDF_TRACE(CDF_MODULE_ID_SME,
@@ -6316,7 +6278,7 @@ static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx,
 		assoc_info.pProfile = profile;
 		if (context) {
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-			if (roam_offload_params->bRoamSynchInProgress)
+			if (session->roam_synch_in_progress)
 				CDF_TRACE(CDF_MODULE_ID_SME,
 					CDF_TRACE_LEVEL_DEBUG,
 					FL("LFR3:Clear Connected info"));
@@ -6461,7 +6423,7 @@ static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx,
 				mac_ctx->roam.configParam.doBMPSWorkaround = 1;
 			}
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-			if (roam_offload_params->bRoamSynchInProgress) {
+			if (session->roam_synch_in_progress) {
 				roam_info.roamSynchInProgress = 1;
 				roam_info.synchAuthStatus =
 					roam_offload_params->authStatus;
@@ -6487,17 +6449,6 @@ static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx,
 				cmd->u.roamCmd.roamId,
 				eCSR_ROAM_ASSOCIATION_COMPLETION,
 				eCSR_ROAM_RESULT_ASSOCIATED);
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-			if (roam_offload_params->bRoamSynchInProgress
-				&& (roam_offload_params->authStatus
-				    == CSR_ROAM_AUTH_STATUS_CONNECTED)) {
-				CDF_TRACE(CDF_MODULE_ID_SME,
-					CDF_TRACE_LEVEL_DEBUG,
-					FL("LFR3:Send Synch Cnf for Auth status connected"));
-				csr_roam_offload_send_synch_cnf(mac_ctx,
-					session_id);
-			}
-#endif
 		}
 
 		csr_roam_completion(mac_ctx, session_id, NULL, cmd,
@@ -6516,7 +6467,7 @@ static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx,
 	 */
 	if (!CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) {
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-		if (roam_offload_params->bRoamSynchInProgress) {
+		if (session->roam_synch_in_progress) {
 			CDF_TRACE(CDF_MODULE_ID_SME,
 				CDF_TRACE_LEVEL_DEBUG,
 				FL
@@ -7837,60 +7788,57 @@ CDF_STATUS csr_roam_save_connected_infomation(tpAniSirGlobal pMac,
 		return CDF_STATUS_E_FAILURE;
 	}
 	pConnectProfile = &pSession->connectedProfile;
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	if (pSession->roamOffloadSynchParams.bRoamSynchInProgress) {
-		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
-			  FL("csr_roam_save_connected_infomation"));
-	}
-#endif
 	if (pConnectProfile->pAddIEAssoc) {
 		cdf_mem_free(pConnectProfile->pAddIEAssoc);
 		pConnectProfile->pAddIEAssoc = NULL;
 	}
-	cdf_mem_set(&pSession->connectedProfile,
-		    sizeof(tCsrRoamConnectedProfile), 0);
-	pConnectProfile->AuthType = pProfile->negotiatedAuthType;
-	pConnectProfile->AuthInfo = pProfile->AuthType;
-	pConnectProfile->CBMode = pProfile->CBMode;     /* *** this may not be valid */
-	pConnectProfile->EncryptionType = pProfile->negotiatedUCEncryptionType;
-	pConnectProfile->EncryptionInfo = pProfile->EncryptionType;
-	pConnectProfile->mcEncryptionType =
-		pProfile->negotiatedMCEncryptionType;
-	pConnectProfile->mcEncryptionInfo = pProfile->mcEncryptionType;
-	pConnectProfile->BSSType = pProfile->BSSType;
-	pConnectProfile->modifyProfileFields.uapsd_mask = pProfile->uapsd_mask;
+	if (!pSession->roam_synch_in_progress) {
+		cdf_mem_set(&pSession->connectedProfile,
+				sizeof(tCsrRoamConnectedProfile), 0);
+		pConnectProfile->AuthType = pProfile->negotiatedAuthType;
+		pConnectProfile->AuthInfo = pProfile->AuthType;
+		pConnectProfile->CBMode = pProfile->CBMode;
+		pConnectProfile->EncryptionType =
+			pProfile->negotiatedUCEncryptionType;
+		pConnectProfile->EncryptionInfo = pProfile->EncryptionType;
+		pConnectProfile->mcEncryptionType =
+			pProfile->negotiatedMCEncryptionType;
+		pConnectProfile->mcEncryptionInfo = pProfile->mcEncryptionType;
+		pConnectProfile->BSSType = pProfile->BSSType;
+		pConnectProfile->modifyProfileFields.uapsd_mask =
+			pProfile->uapsd_mask;
+		cdf_mem_copy(&pConnectProfile->Keys, &pProfile->Keys,
+				sizeof(tCsrKeys));
+		if (pProfile->nAddIEAssocLength) {
+			pConnectProfile->pAddIEAssoc =
+				cdf_mem_malloc(pProfile->nAddIEAssocLength);
+			if (NULL == pConnectProfile->pAddIEAssoc)
+				status = CDF_STATUS_E_NOMEM;
+			else
+				status = CDF_STATUS_SUCCESS;
+			if (!CDF_IS_STATUS_SUCCESS(status)) {
+				sms_log(pMac, LOGE,
+					FL("Failed to allocate memory for IE"));
+				return CDF_STATUS_E_FAILURE;
+			}
+			pConnectProfile->nAddIEAssocLength =
+				pProfile->nAddIEAssocLength;
+			cdf_mem_copy(pConnectProfile->pAddIEAssoc,
+					pProfile->pAddIEAssoc,
+					pProfile->nAddIEAssocLength);
+		}
+#ifdef WLAN_FEATURE_11W
+		pConnectProfile->MFPEnabled = pProfile->MFPEnabled;
+		pConnectProfile->MFPRequired = pProfile->MFPRequired;
+		pConnectProfile->MFPCapable = pProfile->MFPCapable;
+#endif
+	}
+	/* Save bssid */
 	pConnectProfile->operationChannel = pSirBssDesc->channelId;
 	pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval;
 	if (!pConnectProfile->beaconInterval) {
 		sms_log(pMac, LOGW, FL("ERROR: Beacon interval is ZERO"));
 	}
-	cdf_mem_copy(&pConnectProfile->Keys, &pProfile->Keys, sizeof(tCsrKeys));
-	/* saving the addional IE`s like Hot spot indication element and extended capabilities */
-	if (pProfile->nAddIEAssocLength) {
-		pConnectProfile->pAddIEAssoc =
-			cdf_mem_malloc(pProfile->nAddIEAssocLength);
-		if (NULL == pConnectProfile->pAddIEAssoc)
-			status = CDF_STATUS_E_NOMEM;
-		else
-			status = CDF_STATUS_SUCCESS;
-		if (!CDF_IS_STATUS_SUCCESS(status)) {
-			sms_log(pMac, LOGE,
-				FL
-					("Failed to allocate memory for additional IEs"));
-			return CDF_STATUS_E_FAILURE;
-		}
-		pConnectProfile->nAddIEAssocLength =
-			pProfile->nAddIEAssocLength;
-		cdf_mem_copy(pConnectProfile->pAddIEAssoc,
-			     pProfile->pAddIEAssoc,
-			     pProfile->nAddIEAssocLength);
-	}
-#ifdef WLAN_FEATURE_11W
-	pConnectProfile->MFPEnabled = pProfile->MFPEnabled;
-	pConnectProfile->MFPRequired = pProfile->MFPRequired;
-	pConnectProfile->MFPCapable = pProfile->MFPCapable;
-#endif
-	/* Save bssid */
 	csr_get_bss_id_bss_desc(pMac, pSirBssDesc, &pConnectProfile->bssid);
 #ifdef WLAN_FEATURE_VOWIFI_11R
 	if (pSirBssDesc->mdiePresent) {
@@ -16977,7 +16925,7 @@ csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id,
 		return CDF_STATUS_E_FAILURE;
 	}
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	if (session->roamOffloadSynchParams.bRoamSynchInProgress
+	if (session->roam_synch_in_progress
 	    && (ROAM_SCAN_OFFLOAD_STOP == command)) {
 		/*
 		 * When roam synch is in progress for propagation, there is no
@@ -18327,91 +18275,6 @@ void csr_roaming_report_diag_event(tpAniSirGlobal mac_ctx,
 #endif
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-/*----------------------------------------------------------------------------
-* fn     csr_process_roam_offload_synch_ind
-* brief  This will process the roam synch indication received from
-*        lower layers.This function also calls another API to
-*        parse the beacon IE and fill the appropriate fields
-* param  pMac - pMac global structure
-* param  pMsgBuf - Message buffer received from lower layers
-* --------------------------------------------------------------------------*/
-void csr_process_roam_offload_synch_ind(tHalHandle hHal,
-		roam_offload_synch_ind *roam_synch_ind_ptr)
-{
-	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
-	tCsrRoamSession *session_ptr = NULL;
-	uint8_t session_id = roam_synch_ind_ptr->roamedVdevId;
-	session_ptr =  CSR_GET_SESSION(pMac, roam_synch_ind_ptr->roamedVdevId);
-	if (!session_ptr) {
-		sms_log(pMac, LOGE, FL("LFR3: session %d not found "),
-				roam_synch_ind_ptr->roamedVdevId);
-		goto err_synch_rsp;
-	}
-	if (!CDF_IS_STATUS_SUCCESS(csr_scan_save_roam_offload_ap_to_scan_cache(
-					pMac, roam_synch_ind_ptr))) {
-		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
-				"fail to save roam offload AP to scan cache");
-		goto err_synch_rsp;
-	}
-
-	csr_roaming_report_diag_event(pMac, roam_synch_ind_ptr,
-		eCSR_REASON_ROAM_SYNCH_IND);
-	session_ptr->roamOffloadSynchParams.rssi = roam_synch_ind_ptr->rssi;
-	session_ptr->roamOffloadSynchParams.roamReason =
-		roam_synch_ind_ptr->roamReason;
-	session_ptr->roamOffloadSynchParams.roamedVdevId =
-		roam_synch_ind_ptr->roamedVdevId;
-	cdf_copy_macaddr(&session_ptr->roamOffloadSynchParams.bssid,
-			&roam_synch_ind_ptr->bssid);
-	session_ptr->roamOffloadSynchParams.txMgmtPower =
-		roam_synch_ind_ptr->txMgmtPower;
-	session_ptr->roamOffloadSynchParams.authStatus =
-		roam_synch_ind_ptr->authStatus;
-	session_ptr->roamOffloadSynchParams.bRoamSynchInProgress = true;
-	/*Save the BSS descriptor for later use*/
-	session_ptr->roamOffloadSynchParams.bss_desc_ptr =
-		roam_synch_ind_ptr->bss_desc_ptr;
-	pMac->roam.reassocRespLen = roam_synch_ind_ptr->reassocRespLength;
-	pMac->roam.pReassocResp =
-		cdf_mem_malloc(pMac->roam.reassocRespLen);
-	if (NULL == pMac->roam.pReassocResp) {
-		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
-				"Memory allocation for reassoc response failed");
-		goto err_synch_rsp;
-	}
-	cdf_mem_copy(pMac->roam.pReassocResp,
-			(uint8_t *)roam_synch_ind_ptr +
-			roam_synch_ind_ptr->reassocRespOffset,
-			pMac->roam.reassocRespLen);
-
-	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
-			"LFR3:%s: the reassoc resp frame data:", __func__);
-	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
-			pMac->roam.pReassocResp, pMac->roam.reassocRespLen);
-
-	cdf_mem_copy(session_ptr->roamOffloadSynchParams.kck,
-			roam_synch_ind_ptr->kck, SIR_KCK_KEY_LEN);
-	cdf_mem_copy(session_ptr->roamOffloadSynchParams.kek,
-			roam_synch_ind_ptr->kek, SIR_KEK_KEY_LEN);
-	cdf_mem_copy(session_ptr->roamOffloadSynchParams.replay_ctr,
-			roam_synch_ind_ptr->replay_ctr, SIR_REPLAY_CTR_LEN);
-	if (CDF_STATUS_SUCCESS != csr_neighbor_roam_offload_update_preauth_list(
-					pMac, roam_synch_ind_ptr, session_id)) {
-		/**
-		 *Bail out if Roam Offload Synch Response was not even handled.
-		 **/
-		sms_log(pMac, LOGE, FL("Roam Offload Synch Response "
-					"was not processed"));
-		goto err_synch_rsp;
-	}
-
-	csr_neighbor_roam_request_handoff(pMac, session_id);
-
-err_synch_rsp:
-	cdf_mem_free(roam_synch_ind_ptr->bss_desc_ptr);
-	roam_synch_ind_ptr->bss_desc_ptr = NULL;
-}
-
 /*----------------------------------------------------------------------------
 * fn csr_process_ho_fail_ind
 * brief  This function will process the Hand Off Failure indication
@@ -19025,3 +18888,277 @@ fail:
 	msg_return.bodyval = 0;
 	sys_process_mmh_msg(mac, &msg_return);
 }
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * csr_roam_fill_tdls_info() - Fill TDLS information
+ * @roam_info: Roaming information buffer
+ * @join_rsp: Join response which has TDLS info
+ *
+ * Return: None
+ */
+void csr_roam_fill_tdls_info(tCsrRoamInfo *roam_info, tpSirSmeJoinRsp join_rsp)
+{
+	roam_info->tdls_prohibited = join_rsp->tdls_prohibited;
+	roam_info->tdls_chan_swit_prohibited =
+		join_rsp->tdls_chan_swit_prohibited;
+}
+#endif
+
+/**
+ * csr_roam_synch_callback() - SME level callback for roam synch propagation
+ * @mac_ctx: MAC Context
+ * @roam_synch_data: Roam synch data buffer pointer
+ * @bss_desc: BSS descriptor pointer
+ * @reason: Reason for calling the callback
+ *
+ * This callback is registered with WMA and used after roaming happens in
+ * firmware and the call to this routine completes the roam synch
+ * propagation at both CSR and HDD levels. The HDD level propagation
+ * is achieved through the already defined callback for assoc completion
+ * handler.
+ *
+ * Return: None.
+ */
+void csr_roam_synch_callback(tpAniSirGlobal mac_ctx,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc, uint8_t reason)
+{
+	uint8_t session_id = roam_synch_data->roamedVdevId;
+	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
+	tDot11fBeaconIEs *ies_local = NULL;
+	struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info;
+	tCsrRoamInfo *roam_info;
+	tCsrRoamConnectedProfile *conn_profile = NULL;
+	sme_QosAssocInfo assoc_info;
+	struct cdf_mac_addr bcast_mac = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
+	tpAddBssParams add_bss_params;
+	CDF_STATUS status = CDF_STATUS_SUCCESS;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		sms_log(mac_ctx, LOGE, FL("LFR3: Locking failed, bailing out"));
+		return;
+	}
+	if (!session) {
+		sms_log(mac_ctx, LOGE, FL("LFR3: Session not found"));
+		sme_release_global_lock(&mac_ctx->sme);
+		return;
+	}
+	session->roam_synch_in_progress = true;
+	if (reason == ROAMING_TX_QUEUE_DISABLE) {
+		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
+				eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+		sme_release_global_lock(&mac_ctx->sme);
+		return;
+	}
+	session->roam_synch_data = roam_synch_data;
+	if (!CDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies(mac_ctx,
+			bss_desc, &ies_local))) {
+		sms_log(mac_ctx, LOGE, FL("LFR3: fail to parse IEs"));
+		session->roam_synch_in_progress = false;
+		sme_release_global_lock(&mac_ctx->sme);
+		return;
+	}
+	conn_profile = &session->connectedProfile;
+	csr_roam_stop_network(mac_ctx, session_id,
+		session->pCurRoamProfile,
+		bss_desc,
+		ies_local);
+	ps_global_info->remain_in_power_active_till_dhcp = false;
+	session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+	roam_info = cdf_mem_malloc(sizeof(tCsrRoamInfo));
+	if (NULL == roam_info) {
+		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+			FL("LFR3: Mem Alloc failed for roam info"));
+		session->roam_synch_in_progress = false;
+		sme_release_global_lock(&mac_ctx->sme);
+		return;
+	}
+	csr_scan_save_roam_offload_ap_to_scan_cache(mac_ctx, roam_synch_data,
+			bss_desc);
+	cdf_mem_zero(roam_info, sizeof(tCsrRoamInfo));
+	roam_info->sessionId = session_id;
+	csr_roam_call_callback(mac_ctx, roam_synch_data->roamedVdevId,
+		roam_info, 0, eCSR_ROAM_TDLS_STATUS_UPDATE,
+		eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND);
+	cdf_mem_copy(&roam_info->bssid.bytes, &bss_desc->bssId,
+			sizeof(struct cdf_mac_addr));
+	csr_roam_save_connected_infomation(mac_ctx, session_id,
+			session->pCurRoamProfile,
+			bss_desc,
+			ies_local);
+	csr_roam_save_security_rsp_ie(mac_ctx, session_id,
+			session->pCurRoamProfile->negotiatedAuthType,
+			bss_desc, ies_local);
+	roam_info->isESEAssoc = conn_profile->isESEAssoc;
+	if (CSR_IS_ENC_TYPE_STATIC
+		(session->pCurRoamProfile->negotiatedUCEncryptionType) &&
+		!session->pCurRoamProfile->bWPSAssociation) {
+		if (!CDF_IS_STATUS_SUCCESS(
+			csr_roam_issue_set_context_req(mac_ctx,
+				session_id,
+				session->pCurRoamProfile->negotiatedUCEncryptionType,
+				bss_desc,
+				&(bss_desc->bssId),
+				false, true,
+				eSIR_TX_RX, 0, 0, NULL, 0))) {
+			/* NO keys. these key parameters don't matter */
+			sms_log(mac_ctx, LOGE,
+					FL("Set context for unicast fail"));
+			csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_NONE, session_id);
+		}
+		csr_roam_issue_set_context_req(mac_ctx, session_id,
+			session->pCurRoamProfile->negotiatedMCEncryptionType,
+			bss_desc,
+			&bcast_mac.bytes, false, false,
+			eSIR_TX_RX, 0, 0, NULL, 0);
+	}
+	if ((roam_synch_data->authStatus
+				== CSR_ROAM_AUTH_STATUS_AUTHENTICATED)) {
+		CDF_TRACE(CDF_MODULE_ID_SME,
+				CDF_TRACE_LEVEL_DEBUG,
+				FL("LFR3:Don't start waitforkey timer"));
+		csr_roam_substate_change(mac_ctx,
+				eCSR_ROAM_SUBSTATE_NONE, session_id);
+	} else {
+		roam_info->fAuthRequired = true;
+		csr_roam_substate_change(mac_ctx,
+				eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY,
+				session_id);
+
+		ps_global_info->remain_in_power_active_till_dhcp = true;
+		mac_ctx->roam.WaitForKeyTimerInfo.sessionId = session_id;
+		if (!CDF_IS_STATUS_SUCCESS(csr_roam_start_wait_for_key_timer(
+				mac_ctx, CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD))
+		   ) {
+			sms_log(mac_ctx, LOGE, FL
+					("Failed wait for key timer start"));
+			csr_roam_substate_change(mac_ctx,
+					eCSR_ROAM_SUBSTATE_NONE,
+					session_id);
+		}
+	}
+	roam_info->nBeaconLength = 0;
+	roam_info->nAssocReqLength = roam_synch_data->reassoc_req_length -
+		SIR_MAC_HDR_LEN_3A - SIR_MAC_REASSOC_SSID_OFFSET;
+	roam_info->nAssocRspLength = roam_synch_data->reassocRespLength -
+		SIR_MAC_HDR_LEN_3A;
+	roam_info->pbFrames = cdf_mem_malloc(roam_info->nBeaconLength +
+		roam_info->nAssocReqLength + roam_info->nAssocRspLength);
+	if (NULL == roam_info->pbFrames) {
+		sms_log(mac_ctx, LOGE, FL("no memory available"));
+		session->roam_synch_in_progress = false;
+		if (roam_info)
+			cdf_mem_free(roam_info);
+		sme_release_global_lock(&mac_ctx->sme);
+		return;
+	}
+	cdf_mem_zero(roam_info->pbFrames, roam_info->nBeaconLength +
+		roam_info->nAssocReqLength + roam_info->nAssocRspLength);
+	cdf_mem_copy(roam_info->pbFrames,
+			(uint8_t *)roam_synch_data +
+			roam_synch_data->reassoc_req_offset +
+			SIR_MAC_HDR_LEN_3A + SIR_MAC_REASSOC_SSID_OFFSET,
+			roam_info->nAssocReqLength);
+	cdf_mem_copy(roam_info->pbFrames + roam_info->nAssocReqLength,
+			(uint8_t *)roam_synch_data +
+			roam_synch_data->reassocRespOffset +
+			SIR_MAC_HDR_LEN_3A,
+			roam_info->nAssocRspLength);
+
+	CDF_TRACE(CDF_MODULE_ID_SME,
+			CDF_TRACE_LEVEL_DEBUG,
+			FL("LFR3:Clear Connected info"));
+	csr_roam_free_connected_info(mac_ctx,
+			&session->connectedInfo);
+	conn_profile->vht_channel_width =
+		roam_synch_data->join_rsp->vht_channel_width;
+	add_bss_params = (tpAddBssParams)roam_synch_data->add_bss_params;
+	session->connectedInfo.staId = add_bss_params->staContext.staIdx;
+	roam_info->staId = session->connectedInfo.staId;
+	roam_info->ucastSig =
+		(uint8_t) roam_synch_data->join_rsp->ucastSig;
+	roam_info->bcastSig =
+		(uint8_t) roam_synch_data->join_rsp->bcastSig;
+	roam_info->timingMeasCap =
+		roam_synch_data->join_rsp->timingMeasCap;
+	roam_info->chan_info.nss = roam_synch_data->join_rsp->nss;
+	roam_info->chan_info.rate_flags =
+		roam_synch_data->join_rsp->max_rate_flags;
+	csr_roam_fill_tdls_info(roam_info, roam_synch_data->join_rsp);
+	sms_log(mac_ctx, LOG1,
+		FL("tdls:prohibit: %d, chan_swit_prohibit: %d"),
+		roam_info->tdls_prohibited,
+		roam_info->tdls_chan_swit_prohibited);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+	src_profile = &roam_synch_data->join_rsp->HTProfile;
+	dst_profile = &conn_profile->HTProfile;
+	if (mac_ctx->roam.configParam.cc_switch_mode
+			!= CDF_MCC_TO_SCC_SWITCH_DISABLE)
+		csr_roam_copy_ht_profile(dst_profile,
+				src_profile);
+#endif
+	assoc_info.pBssDesc = bss_desc;
+	roam_info->statusCode = eSIR_SME_SUCCESS;
+	roam_info->reasonCode = eSIR_SME_SUCCESS;
+	assoc_info.pProfile = session->pCurRoamProfile;
+	mac_ctx->roam.roamSession[session_id].connectState =
+		eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
+	sme_qos_csr_event_ind(mac_ctx, session_id,
+		SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL);
+	sme_qos_csr_event_ind(mac_ctx, session_id,
+		SME_QOS_CSR_REASSOC_REQ, NULL);
+	sme_qos_csr_event_ind(mac_ctx, session_id,
+		SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
+	mac_ctx->roam.roamSession[session_id].connectState =
+		eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
+	sme_qos_csr_event_ind(mac_ctx, session_id,
+		SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info);
+	roam_info->pBssDesc = bss_desc;
+	conn_profile->acm_mask = sme_qos_get_acm_mask(mac_ctx,
+			bss_desc, NULL);
+	if (conn_profile->modifyProfileFields.uapsd_mask) {
+		sms_log(mac_ctx, LOGE,
+				" uapsd_mask (0x%X) set, request UAPSD now",
+				conn_profile->modifyProfileFields.uapsd_mask);
+		sme_ps_start_uapsd(mac_ctx, session_id,
+				NULL, NULL);
+	}
+	conn_profile->dot11Mode = session->bssParams.uCfgDot11Mode;
+	roam_info->u.pConnectedProfile = conn_profile;
+
+	if (!IS_FEATURE_SUPPORTED_BY_FW
+			(SLM_SESSIONIZATION) &&
+			(csr_is_concurrent_session_running(mac_ctx))) {
+		mac_ctx->roam.configParam.doBMPSWorkaround = 1;
+	}
+	roam_info->roamSynchInProgress = true;
+	roam_info->synchAuthStatus = roam_synch_data->authStatus;
+	cdf_mem_copy(roam_info->kck, roam_synch_data->kck, SIR_KCK_KEY_LEN);
+	cdf_mem_copy(roam_info->kek, roam_synch_data->kek, SIR_KEK_KEY_LEN);
+	cdf_mem_copy(roam_info->replay_ctr, roam_synch_data->replay_ctr,
+			SIR_REPLAY_CTR_LEN);
+	CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
+		FL("LFR3: Copy KCK, KEK and Replay Ctr"));
+	roam_info->subnet_change_status =
+		CSR_GET_SUBNET_STATUS(roam_synch_data->roamReason);
+	csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
+		eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED);
+	csr_reset_pmkid_candidate_list(mac_ctx, session_id);
+#ifdef FEATURE_WLAN_WAPI
+	csr_reset_bkid_candidate_list(mac_ctx, session_id);
+#endif
+	if (!CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) {
+		CDF_TRACE(CDF_MODULE_ID_SME,
+				CDF_TRACE_LEVEL_DEBUG,
+				FL
+				("NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up"));
+		csr_roam_link_up(mac_ctx, conn_profile->bssid);
+	}
+	session->fRoaming = false;
+	session->roam_synch_in_progress = false;
+	cdf_mem_free(roam_info->pbFrames);
+	cdf_mem_free(roam_info);
+	sme_release_global_lock(&mac_ctx->sme);
+}

+ 3 - 2
core/sme/src/csr/csr_api_scan.c

@@ -7102,7 +7102,8 @@ void update_cckmtsf(uint32_t *timeStamp0, uint32_t *timeStamp1,
  */
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 CDF_STATUS csr_scan_save_roam_offload_ap_to_scan_cache(tpAniSirGlobal pMac,
-				roam_offload_synch_ind *roam_sync_ind_ptr)
+		roam_offload_synch_ind *roam_sync_ind_ptr,
+		tpSirBssDescription  bss_desc_ptr)
 {
 	uint32_t length = 0;
 	bool dup_bss;
@@ -7123,7 +7124,7 @@ CDF_STATUS csr_scan_save_roam_offload_ap_to_scan_cache(tpAniSirGlobal pMac,
 
 	cdf_mem_zero(scan_res_ptr, sizeof(tCsrScanResult) + length);
 	cdf_mem_copy(&scan_res_ptr->Result.BssDescriptor,
-			roam_sync_ind_ptr->bss_desc_ptr,
+			bss_desc_ptr,
 			(sizeof(tSirBssDescription) + length));
 	ies_local_ptr = (tDot11fBeaconIEs *)(scan_res_ptr->Result.pvIes);
 	if (!ies_local_ptr &&

+ 10 - 8
core/sme/src/csr/csr_neighbor_roam.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -2480,7 +2480,7 @@ static void csr_neighbor_roam_info_ctx_init(
 		}
 		ngbr_roam_info->uOsRequestedHandoff = 0;
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-		if (session->roamOffloadSynchParams.bRoamSynchInProgress) {
+		if (session->roam_synch_in_progress) {
 			if (pMac->roam.pReassocResp != NULL) {
 				CDF_TRACE(CDF_MODULE_ID_SME,
 					CDF_TRACE_LEVEL_DEBUG,
@@ -2488,9 +2488,6 @@ static void csr_neighbor_roam_info_ctx_init(
 				cdf_mem_free(pMac->roam.pReassocResp);
 				pMac->roam.pReassocResp = NULL;
 			}
-			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
-				"LFR3:Send SynchCnf auth, authenticated");
-			csr_roam_offload_send_synch_cnf(pMac, session_id);
 		} else
 #endif
 			csr_roam_offload_scan(pMac, session_id,
@@ -2554,9 +2551,9 @@ CDF_STATUS csr_neighbor_roam_indicate_connect(
 		return CDF_STATUS_SUCCESS;
 	}
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	if (session->roamOffloadSynchParams.bRoamSynchInProgress &&
+	if (session->roam_synch_in_progress &&
 		(eSIR_ROAM_AUTH_STATUS_AUTHENTICATED ==
-		session->roamOffloadSynchParams.authStatus)) {
+		session->roam_synch_data->authStatus)) {
 		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_DEBUG,
 			"LFR3:csr_neighbor_roam_indicate_connect");
 		msg = cdf_mem_malloc(sizeof(tSirSetActiveModeSetBncFilterReq));
@@ -2572,10 +2569,15 @@ CDF_STATUS csr_neighbor_roam_indicate_connect(
 		cdf_copy_macaddr(&roamInfo.peerMac,
 			&session->connectedProfile.bssid);
 		roamInfo.roamSynchInProgress =
-			session->roamOffloadSynchParams.bRoamSynchInProgress;
+			session->roam_synch_in_progress;
 		csr_roam_call_callback(pMac, session_id, &roamInfo, 0,
 			eCSR_ROAM_SET_KEY_COMPLETE,
 			eCSR_ROAM_RESULT_AUTHENTICATED);
+		csr_neighbor_roam_reset_init_state_control_info(pMac,
+			session_id);
+		csr_neighbor_roam_info_ctx_init(pMac, session_id);
+
+		return status;
 	}
 #endif
 

+ 13 - 13
core/sme/src/qos/sme_qos.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -3822,20 +3822,20 @@ CDF_STATUS sme_qos_process_ft_reassoc_rsp_ev(tpAniSirGlobal mac_ctx,
 				 csr_conn_info->nAssocRspLength));
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	if (!csr_session->roamOffloadSynchParams.bRoamSynchInProgress) {
+	if (!csr_session->roam_synch_in_progress) {
 #endif
-	for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
-		ac_info = &qos_session->ac_info[ac];
-		sme_qos_find_matching_tspec(mac_ctx, sessionid, ac,
-			ac_info, ric_data_desc, &ric_rsplen);
-	}
+		for (ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) {
+			ac_info = &qos_session->ac_info[ac];
+			sme_qos_find_matching_tspec(mac_ctx, sessionid, ac,
+					ac_info, ric_data_desc, &ric_rsplen);
+		}
 
-	if (ric_rsplen) {
-		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
-			  FL("RIC Response still follows despite traversing "
-			  "through all ACs. Remaining len = %d"), ric_rsplen);
-		CDF_ASSERT(0);
-	}
+		if (ric_rsplen) {
+			CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+				FL("RIC Resp still follows . Rem len = %d"),
+				ric_rsplen);
+			CDF_ASSERT(0);
+		}
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	} else {
 		CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,

+ 7 - 1
core/wma/inc/wma.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1367,6 +1367,12 @@ typedef struct {
 	 * the serialized MC thread context with a timer.
 	 */
 	cdf_mc_timer_t service_ready_ext_timer;
+	void (*csr_roam_synch_cb)(tpAniSirGlobal mac,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc_ptr, uint8_t reason);
+	CDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc_ptr);
 } t_wma_handle, *tp_wma_handle;
 
 /**

+ 12 - 2
core/wma/inc/wma_internal.h

@@ -415,8 +415,18 @@ int wma_nlo_scan_cmp_evt_handler(void *handle, uint8_t *event, uint32_t len);
 #endif
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-void wma_process_roam_synch_complete(WMA_HANDLE handle,
-				     tSirSmeRoamOffloadSynchCnf *synchcnf);
+void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id);
+static inline bool wma_is_roam_synch_in_progress(tp_wma_handle wma,
+		uint8_t vdev_id)
+{
+	return wma->interfaces[vdev_id].roam_synch_in_progress;
+}
+#else
+static inline bool wma_is_roam_synch_in_progress(tp_wma_handle wma,
+		uint8_t vdev_id)
+{
+	return false;
+}
 #endif
 
 /*

+ 8 - 3
core/wma/inc/wma_types.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -285,7 +285,6 @@
 #define WMA_ROAM_SCAN_OFFLOAD_REQ   SIR_HAL_ROAM_SCAN_OFFLOAD_REQ
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-#define WMA_ROAM_OFFLOAD_SYNCH_CNF  SIR_HAL_ROAM_OFFLOAD_SYNCH_CNF
 #define WMA_ROAM_OFFLOAD_SYNCH_IND  SIR_HAL_ROAM_OFFLOAD_SYNCH_IND
 #define WMA_ROAM_OFFLOAD_SYNCH_FAIL SIR_HAL_ROAM_OFFLOAD_SYNCH_FAIL
 #endif
@@ -685,6 +684,12 @@ CDF_STATUS wma_register_mgmt_frm_client(void *p_cds_gctx,
 				wma_mgmt_frame_rx_callback mgmt_rx_cb);
 
 CDF_STATUS wma_de_register_mgmt_frm_client(void *p_cds_gctx);
-
+CDF_STATUS wma_register_roaming_callbacks(void *cds_ctx,
+		void (*csr_roam_synch_cb)(tpAniSirGlobal mac,
+			roam_offload_synch_ind *roam_synch_data,
+			tpSirBssDescription  bss_desc_ptr, uint8_t reason),
+		CDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
+			roam_offload_synch_ind *roam_synch_data,
+			tpSirBssDescription  bss_desc_ptr));
 
 #endif

+ 4 - 5
core/wma/src/wma_data.c

@@ -1319,16 +1319,15 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params)
 	}
 
 	if (params->state == eSIR_LINK_PREASSOC_STATE) {
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-		if (wma->interfaces[vdev_id].roam_synch_in_progress) {
+		if (wma_is_roam_synch_in_progress(wma, vdev_id))
 			roam_synch_in_progress = true;
-		}
-#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 		status = wma_create_peer(wma, pdev, vdev, params->bssid,
 				WMI_PEER_TYPE_DEFAULT, vdev_id,
 				roam_synch_in_progress);
 		if (status != CDF_STATUS_SUCCESS)
-			params->status = false;
+			WMA_LOGE("%s: Unable to create peer", __func__);
+		if (roam_synch_in_progress)
+			return;
 	} else {
 		WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP",
 			 __func__, vdev_id);

+ 19 - 26
core/wma/src/wma_dev_if.c

@@ -1068,10 +1068,8 @@ void wma_remove_peer(tp_wma_handle wma, uint8_t *bssid,
 	wma->interfaces[vdev_id].peer_count--;
 	WMA_LOGE("%s: Removed peer with peer_addr %pM vdevid %d peer_count %d",
 		 __func__, bssid, vdev_id, wma->interfaces[vdev_id].peer_count);
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	if (roam_synch_in_progress)
 		return;
-#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 	/* Flush all TIDs except MGMT TID for this peer in Target */
 	peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID);
 	wmi_unified_peer_flush_tids_send(wma->wmi_handle, bssid,
@@ -1158,15 +1156,13 @@ CDF_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev,
 		WMA_LOGE("%s : Unable to attach peer %pM", __func__, peer_addr);
 		goto err;
 	}
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	if (roam_synch_in_progress) {
 
-		WMA_LOGE("%s: Created peer with peer_addr %pM vdev_id %d,"
+		WMA_LOGE("%s: LFR3: Created peer with peer_addr %pM vdev_id %d,"
 			 "peer_count - %d", __func__, peer_addr, vdev_id,
 			 wma->interfaces[vdev_id].peer_count);
 		return CDF_STATUS_SUCCESS;
 	}
-#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 	if (wmi_unified_peer_create_send(wma->wmi_handle, peer_addr,
 					 peer_type, vdev_id) < 0) {
 		WMA_LOGP("%s : Unable to create peer in Target", __func__);
@@ -3222,13 +3218,14 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
 					 add_bss->bssId);
 				goto send_fail_resp;
 			}
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-			if (iface->roam_synch_in_progress) {
+			if (wma_is_roam_synch_in_progress(wma, vdev_id)) {
 				add_bss->staContext.staIdx =
 					ol_txrx_local_peer_id(peer);
-				goto send_bss_resp;
+				WMA_LOGD("LFR3:%s: bssid %pM staIdx %d",
+					__func__, add_bss->bssId,
+					add_bss->staContext.staIdx);
+				return;
 			}
-#endif
 			msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ,
 						WMA_TARGET_REQ_TYPE_VDEV_START,
 						add_bss,
@@ -3900,7 +3897,6 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
 		status = CDF_STATUS_E_FAILURE;
 		goto out;
 	}
-
 	if (peer != NULL && peer->state == ol_txrx_peer_state_disc) {
 		/*
 		 * This is the case for reassociation.
@@ -3921,8 +3917,7 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
 						  ol_txrx_peer_state_conn);
 		}
 
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-		if (iface->roam_synch_in_progress) {
+		if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) {
 			/* iface->nss = params->nss; */
 			/*In LFR2.0, the following operations are performed as
 			 * part of wmi_unified_send_peer_assoc. As we are
@@ -3933,9 +3928,11 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
 			cdf_atomic_set(&iface->bss_status,
 				       WMA_BSS_STATUS_STARTED);
 			iface->aid = params->assocId;
-			goto out;
+			WMA_LOGE("LFR3:statype %d vdev %d aid %d bssid %pM",
+					params->staType, params->smesessionId,
+					params->assocId, params->bssId);
+			return;
 		}
-#endif
 		wmi_unified_send_txbf(wma, params);
 
 		if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
@@ -4199,20 +4196,13 @@ static void wma_delete_sta_req_sta_mode(tp_wma_handle wma,
 	iface = &wma->interfaces[params->smesessionId];
 	iface->uapsd_cached_val = 0;
 
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	/* In case of LFR3.0 we need not send any
-	 * WMI commands to FW before SYNCH_CONFIRM */
-	if (iface->roam_synch_in_progress)
-		goto send_del_sta_rsp;
-#endif
+	if (wma_is_roam_synch_in_progress(wma, params->smesessionId))
+		return;
 #ifdef FEATURE_WLAN_TDLS
 	if (STA_ENTRY_TDLS_PEER == params->staType) {
 		wma_del_tdls_sta(wma, params);
 		return;
 	}
-#endif
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-send_del_sta_rsp:
 #endif
 	params->status = status;
 	if (params->respReqd) {
@@ -4288,6 +4278,8 @@ void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
 	switch (oper_mode) {
 	case BSS_OPERATIONAL_MODE_STA:
 		wma_delete_sta_req_sta_mode(wma, del_sta);
+		if (wma_is_roam_synch_in_progress(wma, smesession_id))
+			return;
 		break;
 
 	case BSS_OPERATIONAL_MODE_IBSS: /* IBSS shares AP code */
@@ -4405,15 +4397,13 @@ void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
 	if (wlan_op_mode_ibss == txrx_vdev->opmode) {
 		wma->ibss_started = 0;
 	}
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	if (wma->interfaces[params->smesessionId].roam_synch_in_progress) {
+	if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) {
 		roam_synch_in_progress = true;
 		WMA_LOGD("LFR3:%s: Setting vdev_up to FALSE for session %d",
 			__func__, params->smesessionId);
 		wma->interfaces[params->smesessionId].vdev_up = false;
 		goto detach_peer;
 	}
-#endif
 	msg = wma_fill_vdev_req(wma, params->smesessionId, WMA_DELETE_BSS_REQ,
 				WMA_TARGET_REQ_TYPE_VDEV_STOP, params,
 				WMA_VDEV_STOP_REQUEST_TIMEOUT);
@@ -4463,6 +4453,9 @@ void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
 detach_peer:
 	wma_remove_peer(wma, params->bssid, params->smesessionId, peer,
 			roam_synch_in_progress);
+	if (wma_is_roam_synch_in_progress(wma, params->smesessionId))
+		return;
+
 out:
 	params->status = status;
 	wma_send_msg(wma, WMA_DELETE_BSS_RSP, (void *)params, 0);

+ 0 - 5
core/wma/src/wma_main.c

@@ -5140,11 +5140,6 @@ CDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
 		cdf_mem_free(msg->bodyptr);
 		break;
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	case WMA_ROAM_OFFLOAD_SYNCH_CNF:
-		wma_process_roam_synch_complete(wma_handle,
-			(tSirSmeRoamOffloadSynchCnf *)msg->bodyptr);
-		cdf_mem_free(msg->bodyptr);
-		break;
 	case WMA_ROAM_OFFLOAD_SYNCH_FAIL:
 		wma_process_roam_synch_fail(wma_handle,
 			(struct roam_offload_synch_fail *)msg->bodyptr);

+ 31 - 0
core/wma/src/wma_mgmt.c

@@ -3330,6 +3330,37 @@ CDF_STATUS wma_de_register_mgmt_frm_client(void *cds_ctx)
 	return CDF_STATUS_SUCCESS;
 }
 
+/**
+ * wma_register_roaming_callbacks() - Register roaming callbacks
+ * @cds_ctx: CDS Context
+ * @csr_roam_synch_cb: CSR roam synch callback routine pointer
+ * @pe_roam_synch_cb: PE roam synch callback routine pointer
+ *
+ * Register the SME and PE callback routines with WMA for
+ * handling roaming
+ *
+ * Return: Success or Failure Status
+ */
+CDF_STATUS wma_register_roaming_callbacks(void *cds_ctx,
+	void (*csr_roam_synch_cb)(tpAniSirGlobal mac,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc_ptr, uint8_t reason),
+	CDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
+		roam_offload_synch_ind *roam_synch_data,
+		tpSirBssDescription  bss_desc_ptr))
+{
+
+	tp_wma_handle wma = cds_get_context(CDF_MODULE_ID_WMA);
+
+	if (!wma) {
+		WMA_LOGE("%s: Failed to get WMA context", __func__);
+		return CDF_STATUS_E_FAILURE;
+	}
+	wma->csr_roam_synch_cb = csr_roam_synch_cb;
+	wma->pe_roam_synch_cb = pe_roam_synch_cb;
+	WMA_LOGD("Registered roam synch callbacks with WMA successfully");
+	return CDF_STATUS_SUCCESS;
+}
 /**
  * wma_register_mgmt_frm_client() - register management frame callback
  * @cds_ctx: cds context

+ 188 - 82
core/wma/src/wma_scan_roam.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -2713,74 +2713,30 @@ void wma_process_roam_synch_fail(WMA_HANDLE handle,
 }
 
 /**
- * wma_roam_synch_event_handler() - roam synch event handler
- * @handle: wma handle
- * @event: event data
- * @len: length of data
+ * wma_fill_roam_synch_buffer() - Fill the the roam sync buffer
+ * @wma: Global WMA Handle
+ * @roam_synch_ind_ptr: Buffer to be filled
+ * @param_buf: Source buffer
  *
- * This function is roam synch event handler. It sends roam
- * indication for upper layer.
+ * Firmware sends all the required information required for roam
+ * synch propagation as TLV's and stored in param_buf. These
+ * parameters are parsed and filled into the roam synch indication
+ * buffer which will be used at different layers for propagation.
+ *
+ * Return: None
  */
-int wma_roam_synch_event_handler(void *handle, uint8_t *event,
-					uint32_t len)
+void wma_fill_roam_synch_buffer(tp_wma_handle wma,
+		roam_offload_synch_ind *roam_synch_ind_ptr,
+		WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf)
 {
-	WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf = NULL;
-	wmi_roam_synch_event_fixed_param *synch_event = NULL;
-	uint8_t *bcn_probersp_ptr = NULL;
-	uint8_t *reassoc_rsp_ptr = NULL;
-	uint8_t *reassoc_req_ptr = NULL;
-	tp_wma_handle wma = (tp_wma_handle) handle;
-	wmi_channel *chan = NULL;
-	wmi_key_material *key = NULL;
-	int size = 0;
-	roam_offload_synch_ind *roam_synch_ind_ptr;
-
-	WMA_LOGD("LFR3:%s", __func__);
-	if (!event) {
-		WMA_LOGE("%s: event param null", __func__);
-		return -EINVAL;
-	}
-
-	param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *) event;
-	if (!param_buf) {
-		WMA_LOGE("%s: received null buf from target", __func__);
-		return -EINVAL;
-	}
+	wmi_roam_synch_event_fixed_param *synch_event;
+	uint8_t *bcn_probersp_ptr;
+	uint8_t *reassoc_rsp_ptr;
+	uint8_t *reassoc_req_ptr;
+	wmi_channel *chan;
+	wmi_key_material *key;
 
 	synch_event = param_buf->fixed_param;
-	if (!synch_event) {
-		WMA_LOGE("%s: received null event data from target", __func__);
-		return -EINVAL;
-	}
-
-	if (wma->interfaces[synch_event->vdev_id].roam_synch_in_progress) {
-		WMA_LOGE("%s: Ignoring RSI since one is already in progress",
-				__func__);
-		return -EINVAL;
-	}
-	wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = true;
-	len = sizeof(roam_offload_synch_ind) +
-	      synch_event->bcn_probe_rsp_len + synch_event->reassoc_rsp_len +
-	      synch_event->reassoc_req_len;
-	roam_synch_ind_ptr =
-		(roam_offload_synch_ind *) cdf_mem_malloc(len);
-	if (!roam_synch_ind_ptr) {
-		WMA_LOGE("%s: failed to allocate memory for roam_synch_event",
-			 __func__);
-		return -ENOMEM;
-	}
-
-	/* abort existing scan if any */
-	if (wma->interfaces[synch_event->vdev_id].scan_info.scan_id != 0) {
-		tAbortScanParams abort_scan;
-		WMA_LOGD("LFR3: Aborting Scan with scan_id=%d\n",
-		wma->interfaces[synch_event->vdev_id].scan_info.scan_id);
-		abort_scan.SessionId = synch_event->vdev_id;
-		wma_stop_scan(wma, &abort_scan);
-	}
-
-	roam_synch_ind_ptr->messageType = eWNI_SME_ROAM_OFFLOAD_SYNCH_IND;
-	roam_synch_ind_ptr->length = size;
 	roam_synch_ind_ptr->roamedVdevId = synch_event->vdev_id;
 	roam_synch_ind_ptr->authStatus = synch_event->auth_status;
 	roam_synch_ind_ptr->roamReason = synch_event->roam_reason;
@@ -2788,17 +2744,17 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event,
 	roam_synch_ind_ptr->isBeacon = synch_event->is_beacon;
 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid,
 				   roam_synch_ind_ptr->bssid.bytes);
+	wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
+		roam_synch_ind_ptr, NULL, ROAMING_TX_QUEUE_DISABLE);
 	/* Beacon/Probe Rsp data */
 	roam_synch_ind_ptr->beaconProbeRespOffset =
 		sizeof(roam_offload_synch_ind);
-	bcn_probersp_ptr =
-		(uint8_t *) roam_synch_ind_ptr +
+	bcn_probersp_ptr = (uint8_t *) roam_synch_ind_ptr +
 		roam_synch_ind_ptr->beaconProbeRespOffset;
 	roam_synch_ind_ptr->beaconProbeRespLength =
 		synch_event->bcn_probe_rsp_len;
 	cdf_mem_copy(bcn_probersp_ptr, param_buf->bcn_probe_rsp_frame,
 		     roam_synch_ind_ptr->beaconProbeRespLength);
-
 	/* ReAssoc Rsp data */
 	roam_synch_ind_ptr->reassocRespOffset =
 		sizeof(roam_offload_synch_ind) +
@@ -2841,8 +2797,169 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event,
 		CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_DEBUG,
 				   key->replay_counter, SIR_REPLAY_CTR_LEN);
 	}
-	wma_send_msg(wma, WMA_ROAM_OFFLOAD_SYNCH_IND,
-			(void *) roam_synch_ind_ptr, 0);
+}
+
+/**
+ * wma_roam_update_vdev() - Update the STA and BSS
+ * @wma: Global WMA Handle
+ * @roam_synch_ind_ptr: Information needed for roam sync propagation
+ *
+ * This function will perform all the vdev related operations with
+ * respect to the self sta and the peer after roaming and completes
+ * the roam synch propagation with respect to WMA layer.
+ *
+ * Return: None
+ */
+void wma_roam_update_vdev(tp_wma_handle wma,
+	roam_offload_synch_ind *roam_synch_ind_ptr)
+{
+	tDeleteBssParams *del_bss_params;
+	tDeleteStaParams *del_sta_params;
+	tLinkStateParams *set_link_params;
+	tAddStaParams *add_sta_params;
+	uint8_t vdev_id;
+
+	del_bss_params = cdf_mem_malloc(sizeof(*del_bss_params));
+	del_sta_params = cdf_mem_malloc(sizeof(*del_sta_params));
+	set_link_params = cdf_mem_malloc(sizeof(*set_link_params));
+	add_sta_params = cdf_mem_malloc(sizeof(*add_sta_params));
+	if (!del_bss_params || !del_sta_params ||
+		!set_link_params || !add_sta_params) {
+		WMA_LOGE("%s: failed to allocate memory", __func__);
+		return;
+	}
+	vdev_id = roam_synch_ind_ptr->roamedVdevId;
+	cdf_mem_zero(del_bss_params, sizeof(*del_bss_params));
+	cdf_mem_zero(del_sta_params, sizeof(*del_sta_params));
+	cdf_mem_zero(set_link_params, sizeof(*set_link_params));
+	cdf_mem_zero(add_sta_params, sizeof(*add_sta_params));
+
+	del_bss_params->smesessionId = vdev_id;
+	del_sta_params->smesessionId = vdev_id;
+	cdf_mem_copy(del_bss_params->bssid, wma->interfaces[vdev_id].bssid,
+			IEEE80211_ADDR_LEN);
+	set_link_params->state = eSIR_LINK_PREASSOC_STATE;
+	cdf_mem_copy(set_link_params->selfMacAddr, wma->myaddr,
+			IEEE80211_ADDR_LEN);
+	cdf_mem_copy(set_link_params->bssid, roam_synch_ind_ptr->bssid.bytes,
+			IEEE80211_ADDR_LEN);
+	add_sta_params->staType = STA_ENTRY_SELF;
+	add_sta_params->smesessionId = vdev_id;
+	cdf_mem_copy(&add_sta_params->bssId, &roam_synch_ind_ptr->bssid.bytes,
+			IEEE80211_ADDR_LEN);
+	add_sta_params->staIdx = STA_INVALID_IDX;
+	add_sta_params->assocId = roam_synch_ind_ptr->aid;
+
+	wma_delete_sta(wma, del_sta_params);
+	wma_delete_bss(wma, del_bss_params);
+	wma_set_linkstate(wma, set_link_params);
+	wma_add_bss(wma, (tpAddBssParams)roam_synch_ind_ptr->add_bss_params);
+	wma_add_sta(wma, add_sta_params);
+	wma->interfaces[vdev_id].vdev_up = true;
+	cdf_mem_copy(wma->interfaces[vdev_id].bssid,
+			roam_synch_ind_ptr->bssid.bytes, IEEE80211_ADDR_LEN);
+	cdf_mem_free(del_bss_params);
+	cdf_mem_free(del_sta_params);
+	cdf_mem_free(set_link_params);
+	cdf_mem_free(add_sta_params);
+}
+
+/**
+ * wma_roam_synch_event_handler() - roam synch event handler
+ * @handle: wma handle
+ * @event: event data
+ * @len: length of data
+ *
+ * This function is roam synch event handler. It sends roam
+ * indication for upper layer.
+ *
+ * Return: Success or Failure status
+ */
+int wma_roam_synch_event_handler(void *handle, uint8_t *event,
+					uint32_t len)
+{
+	WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf = NULL;
+	wmi_roam_synch_event_fixed_param *synch_event = NULL;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+	roam_offload_synch_ind *roam_synch_ind_ptr;
+	tpSirBssDescription  bss_desc_ptr = NULL;
+	uint16_t ie_len = 0;
+	int status = -EINVAL;
+
+	WMA_LOGD("LFR3:%s", __func__);
+	if (!event) {
+		WMA_LOGE("%s: event param null", __func__);
+		return status;
+	}
+
+	param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *) event;
+	if (!param_buf) {
+		WMA_LOGE("%s: received null buf from target", __func__);
+		return status;
+	}
+
+	synch_event = param_buf->fixed_param;
+	if (!synch_event) {
+		WMA_LOGE("%s: received null event data from target", __func__);
+		return status;
+	}
+
+	if (wma_is_roam_synch_in_progress(wma, synch_event->vdev_id)) {
+		WMA_LOGE("%s: Ignoring RSI since one is already in progress",
+				__func__);
+		return status;
+	}
+
+	wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = true;
+	len = sizeof(roam_offload_synch_ind) +
+	      synch_event->bcn_probe_rsp_len + synch_event->reassoc_rsp_len +
+	      synch_event->reassoc_req_len;
+	roam_synch_ind_ptr =
+		(roam_offload_synch_ind *) cdf_mem_malloc(len);
+	if (!roam_synch_ind_ptr) {
+		WMA_LOGE("%s: failed to allocate memory for roam_synch_event",
+			 __func__);
+		CDF_ASSERT(roam_synch_ind_ptr != NULL);
+		return -ENOMEM;
+	}
+	cdf_mem_zero(roam_synch_ind_ptr, len);
+	wma_fill_roam_synch_buffer(wma, roam_synch_ind_ptr, param_buf);
+
+	 /* 24 byte MAC header and 12 byte to ssid IE */
+	if (roam_synch_ind_ptr->beaconProbeRespLength >
+			(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) {
+		ie_len = roam_synch_ind_ptr->beaconProbeRespLength -
+			(SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
+	} else {
+		WMA_LOGE("LFR3: Invalid Beacon Length");
+		goto cleanup_label;
+	}
+	bss_desc_ptr = cdf_mem_malloc(sizeof(tSirBssDescription) + ie_len);
+	roam_synch_ind_ptr->join_rsp = cdf_mem_malloc(sizeof(tSirSmeJoinRsp));
+	if ((NULL == roam_synch_ind_ptr->join_rsp) || (NULL == bss_desc_ptr)) {
+		WMA_LOGE("LFR3: mem alloc failed!");
+		CDF_ASSERT(bss_desc_ptr != NULL);
+		CDF_ASSERT(roam_synch_ind_ptr->join_rsp != NULL);
+		status =  -ENOMEM;
+		goto cleanup_label;
+	}
+	cdf_mem_zero(roam_synch_ind_ptr->join_rsp, sizeof(tSirSmeJoinRsp));
+	cdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription) + ie_len);
+	wma->pe_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
+			roam_synch_ind_ptr, bss_desc_ptr);
+	wma_roam_update_vdev(wma, roam_synch_ind_ptr);
+	wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
+		roam_synch_ind_ptr, bss_desc_ptr, ROAM_SYNCH_PROPAGATION);
+	wma_process_roam_synch_complete(wma, synch_event->vdev_id);
+cleanup_label:
+	if (roam_synch_ind_ptr->join_rsp)
+		cdf_mem_free(roam_synch_ind_ptr->join_rsp);
+	if (roam_synch_ind_ptr)
+		cdf_mem_free(roam_synch_ind_ptr);
+	if (bss_desc_ptr)
+		cdf_mem_free(bss_desc_ptr);
+	wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = false;
+
 	return 0;
 }
 
@@ -3267,15 +3384,13 @@ static void wma_roam_ho_fail_handler(tp_wma_handle wma, uint32_t vdev_id)
  *
  * Return: none
  */
-void wma_process_roam_synch_complete(WMA_HANDLE handle,
-				     tSirSmeRoamOffloadSynchCnf *synchcnf)
+void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id)
 {
 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
 	wmi_roam_synch_complete_fixed_param *cmd;
 	wmi_buf_t wmi_buf;
 	uint8_t *buf_ptr;
 	uint16_t len;
-	bool roam_synch_in_progress;
 	len = sizeof(wmi_roam_synch_complete_fixed_param);
 
 	if (!wma_handle || !wma_handle->wmi_handle) {
@@ -3283,15 +3398,6 @@ void wma_process_roam_synch_complete(WMA_HANDLE handle,
 			 __func__);
 		return;
 	}
-	roam_synch_in_progress =
-		wma_handle->interfaces[synchcnf->sessionId].roam_synch_in_progress;
-	if (roam_synch_in_progress == false) {
-		WMA_LOGE("%s: Dont send roam synch complete", __func__);
-		return;
-	} else {
-		wma_handle->interfaces[synchcnf->sessionId].roam_synch_in_progress =
-			false;
-	}
 	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
 	if (!wmi_buf) {
 		WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
@@ -3303,7 +3409,7 @@ void wma_process_roam_synch_complete(WMA_HANDLE handle,
 		       WMITLV_TAG_STRUC_wmi_roam_synch_complete_fixed_param,
 		       WMITLV_GET_STRUCT_TLVLEN
 			       (wmi_roam_synch_complete_fixed_param));
-	cmd->vdev_id = synchcnf->sessionId;
+	cmd->vdev_id = vdev_id;
 	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
 				 WMI_ROAM_SYNCH_COMPLETE)) {
 		WMA_LOGP("%s: failed to send roam synch confirmation",