diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index b9a95785e119..3549c7b2d5e1 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/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 diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index d9808e883fcb..cdd34a79f3a7 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/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); diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 149f36116f4a..bd2853f875ff 100644 --- a/core/mac/inc/sir_api.h +++ b/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; diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 12b874d5f02b..64235814b2e9 100644 --- a/core/mac/inc/wni_api.h +++ b/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 diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h index 99e2fc7376cc..bf612454958f 100644 --- a/core/mac/src/pe/include/lim_api.h +++ b/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 */ diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index c7bf4239c2af..14fcfb71cc21 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/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; + ft_session_ptr->limSystemRole = eLIM_STA_ROLE; + sir_copy_mac_addr(session_ptr->limReAssocbssId, bss_desc->bssId); + ft_session_ptr->csaOffloadEnable = session_ptr->csaOffloadEnable; - 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; + 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->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); + + 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_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; - - 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); + 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 diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index 3cd37489f05a..3c47c79b0cd9 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/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 diff --git a/core/mac/src/pe/lim/lim_assoc_utils.h b/core/mac/src/pe/lim/lim_assoc_utils.h index b9efbff3c842..f869ad3b7fa9 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.h +++ b/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 */ diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c index ffab46808c22..72784141a56a 100644 --- a/core/mac/src/pe/lim/lim_ft.c +++ b/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; diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 8e0ed5a1ab33..336460fb8233 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/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; } diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index aa73bca79dfa..bb731323dbdf 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/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; diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 03121a6019fe..da1d9b60001c 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/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"));) diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c index 7cb5eb1d8bb2..bbabde1c834f 100644 --- a/core/mac/src/pe/lim/lim_process_tdls.c +++ b/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; diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 10b000bb9227..2c5e1026ed79 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/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); diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 0b16d7b54787..1bb5b5c0b9eb 100644 --- a/core/sme/inc/csr_api.h +++ b/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 diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index bc82612bcdfd..1140a54ed4dd 100644 --- a/core/sme/inc/csr_internal.h +++ b/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, diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h index 64ca970571bb..1b888b6a2a78 100644 --- a/core/sme/inc/csr_neighbor_roam.h +++ b/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 */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 92bbe82a8a8d..a1d4a534a384 100644 --- a/core/sme/src/common/sme_api.c +++ b/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")); diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index b5af6635e9bc..813c2c7a9036 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/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); +} diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 7a6e1155eab8..20293af2a9f0 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/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 && diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c index a66bfaadf971..40f282787327 100644 --- a/core/sme/src/csr/csr_neighbor_roam.c +++ b/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 diff --git a/core/sme/src/qos/sme_qos.c b/core/sme/src/qos/sme_qos.c index 8372a1fa20d3..ac80f810a083 100644 --- a/core/sme/src/qos/sme_qos.c +++ b/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, diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 3906d6d74312..b9ea71fac370 100644 --- a/core/wma/inc/wma.h +++ b/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; /** diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index ab9ebf89722b..9a2cad03eed9 100644 --- a/core/wma/inc/wma_internal.h +++ b/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 /* diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index d769a78555b6..0a6428a6e36c 100644 --- a/core/wma/inc/wma_types.h +++ b/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 diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 2c2a41c4b843..e93e49979d86 100644 --- a/core/wma/src/wma_data.c +++ b/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); diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 0fd66336c6ee..8d906c2f51a4 100644 --- a/core/wma/src/wma_dev_if.c +++ b/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); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 95cc3aa87e29..718c66dc9bb6 100644 --- a/core/wma/src/wma_main.c +++ b/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); diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 215b450ba824..6827e25ce207 100644 --- a/core/wma/src/wma_mgmt.c +++ b/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 diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index d4bb3367ecf2..83c6eaa275ac 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/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",