| /* |
| * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * This file was originally distributed by Qualcomm Atheros, Inc. |
| * under proprietary terms before Copyright ownership was assigned |
| * to the Linux Foundation. |
| */ |
| |
| #ifdef WLAN_FEATURE_VOWIFI_11R |
| /**========================================================================= |
| |
| \brief implementation for PE 11r VoWiFi FT Protocol |
| |
| ========================================================================*/ |
| |
| /* $Header$ */ |
| |
| /*-------------------------------------------------------------------------- |
| Include Files |
| ------------------------------------------------------------------------*/ |
| #include <lim_send_messages.h> |
| #include <lim_types.h> |
| #include <lim_ft.h> |
| #include <lim_ft_defs.h> |
| #include <lim_utils.h> |
| #include <lim_prop_exts_utils.h> |
| #include <lim_assoc_utils.h> |
| #include <lim_session.h> |
| #include <lim_admit_control.h> |
| #include "wmm_apsd.h" |
| |
| extern void lim_send_set_sta_key_req(tpAniSirGlobal pMac, |
| tLimMlmSetKeysReq *pMlmSetKeysReq, |
| uint16_t staIdx, |
| uint8_t defWEPIdx, |
| tpPESession sessionEntry, bool sendRsp); |
| |
| /*-------------------------------------------------------------------------- |
| Initialize the FT variables. |
| ------------------------------------------------------------------------*/ |
| void lim_ft_open(tpAniSirGlobal pMac, tpPESession psessionEntry) |
| { |
| if (psessionEntry) |
| cdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), |
| 0); |
| } |
| |
| /*-------------------------------------------------------------------------- |
| Cleanup FT variables. |
| ------------------------------------------------------------------------*/ |
| void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac, tpPESession psessionEntry) |
| { |
| tpPESession pReAssocSessionEntry = NULL; |
| uint8_t sessionId = 0; |
| |
| if (!psessionEntry) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, "%s: psessionEntry is NULL", __func__); |
| ) |
| #endif |
| return; |
| } |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return; |
| } |
| |
| if (psessionEntry->ftPEContext.pFTPreAuthReq) { |
| pReAssocSessionEntry = |
| pe_find_session_by_bssid(pMac, |
| psessionEntry->ftPEContext. |
| pFTPreAuthReq->preAuthbssId, |
| &sessionId); |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOG1(lim_log(pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"), |
| psessionEntry->ftPEContext.pFTPreAuthReq); |
| ) |
| #endif |
| if (psessionEntry->ftPEContext.pFTPreAuthReq-> |
| pbssDescription) { |
| cdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq-> |
| pbssDescription); |
| psessionEntry->ftPEContext.pFTPreAuthReq-> |
| pbssDescription = NULL; |
| } |
| cdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq); |
| psessionEntry->ftPEContext.pFTPreAuthReq = NULL; |
| } |
| |
| if (psessionEntry->ftPEContext.pAddBssReq) { |
| cdf_mem_free(psessionEntry->ftPEContext.pAddBssReq); |
| psessionEntry->ftPEContext.pAddBssReq = NULL; |
| } |
| |
| if (psessionEntry->ftPEContext.pAddStaReq) { |
| cdf_mem_free(psessionEntry->ftPEContext.pAddStaReq); |
| psessionEntry->ftPEContext.pAddStaReq = NULL; |
| } |
| |
| /* The session is being deleted, cleanup the contents */ |
| cdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0); |
| |
| /* Delete the session created while handling pre-auth response */ |
| if (pReAssocSessionEntry) { |
| /* If we have successful pre-auth response, then we would have |
| * created a session on which reassoc request will be sent |
| */ |
| if (pReAssocSessionEntry->valid && |
| pReAssocSessionEntry->limSmeState == |
| eLIM_SME_WT_REASSOC_STATE) { |
| CDF_TRACE(CDF_MODULE_ID_PE, |
| CDF_TRACE_LEVEL_DEBUG, |
| FL("Deleting Preauth session(%d)"), |
| pReAssocSessionEntry->peSessionId); |
| pe_delete_session(pMac, pReAssocSessionEntry); |
| } |
| } |
| } |
| |
| void lim_ft_cleanup_all_ft_sessions(tpAniSirGlobal pMac) |
| { |
| /* Wrapper function to cleanup all FT sessions */ |
| int i; |
| |
| for (i = 0; i < pMac->lim.maxBssId; i++) { |
| if (true == pMac->lim.gpSession[i].valid) { |
| /* The session is valid, may have FT data */ |
| lim_ft_cleanup(pMac, &pMac->lim.gpSession[i]); |
| } |
| } |
| } |
| |
| void lim_ft_cleanup(tpAniSirGlobal pMac, tpPESession psessionEntry) |
| { |
| if (NULL == psessionEntry) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log(pMac, LOGE, FL("psessionEntry is NULL"));) |
| #endif |
| return; |
| } |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return; |
| } |
| |
| if (NULL != psessionEntry->ftPEContext.pFTPreAuthReq) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOG1(lim_log(pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"), |
| psessionEntry->ftPEContext.pFTPreAuthReq); |
| ) |
| #endif |
| if (NULL != |
| psessionEntry->ftPEContext.pFTPreAuthReq-> |
| pbssDescription) { |
| cdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq-> |
| pbssDescription); |
| psessionEntry->ftPEContext.pFTPreAuthReq-> |
| pbssDescription = NULL; |
| } |
| cdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq); |
| psessionEntry->ftPEContext.pFTPreAuthReq = NULL; |
| } |
| |
| if (psessionEntry->ftPEContext.pAddBssReq) { |
| cdf_mem_free(psessionEntry->ftPEContext.pAddBssReq); |
| psessionEntry->ftPEContext.pAddBssReq = NULL; |
| } |
| |
| if (psessionEntry->ftPEContext.pAddStaReq) { |
| cdf_mem_free(psessionEntry->ftPEContext.pAddStaReq); |
| psessionEntry->ftPEContext.pAddStaReq = NULL; |
| } |
| |
| /* The session is being deleted, cleanup the contents */ |
| cdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0); |
| } |
| |
| /*------------------------------------------------------------------ |
| * |
| * This is the handler after suspending the link. |
| * We suspend the link and then now proceed to switch channel. |
| * |
| *------------------------------------------------------------------*/ |
| void static |
| lim_ft_pre_auth_suspend_link_handler(tpAniSirGlobal pMac, CDF_STATUS status, |
| uint32_t *data) |
| { |
| tpPESession psessionEntry = (tpPESession) data; |
| |
| /* The link is suspended of not */ |
| if (NULL == psessionEntry || |
| NULL == psessionEntry->ftPEContext.pFTPreAuthReq || |
| status != CDF_STATUS_SUCCESS) { |
| PELOGE(lim_log(pMac, LOGE, |
| FL("preAuth error, status = %d"), status); |
| ) |
| lim_post_ft_pre_auth_rsp(pMac, eSIR_FAILURE, NULL, 0, |
| psessionEntry); |
| return; |
| } |
| |
| /* Suspended, now move to a different channel. |
| * Perform some sanity check before proceeding |
| */ |
| if (psessionEntry->ftPEContext.pFTPreAuthReq) { |
| lim_change_channel_with_callback(pMac, |
| psessionEntry->ftPEContext. |
| pFTPreAuthReq->preAuthchannelNum, |
| lim_perform_ft_pre_auth, NULL, |
| psessionEntry); |
| return; |
| } |
| } |
| |
| /* |
| * lim_process_ft_pre_auth_req() - process ft pre auth req |
| * |
| * @mac_ctx: global mac ctx |
| * @msg: pointer to message |
| * |
| * In this function, we process the FT Pre Auth Req: |
| * We receive Pre-Auth, suspend link, register a call back. In the call back, |
| * we will need to accept frames from the new bssid. Send out the auth req to |
| * new AP. Start timer and when the timer is done or if we receive the Auth |
| * response. We change channel. Resume link |
| * |
| * Return: value to indicate if buffer was consumed |
| */ |
| int lim_process_ft_pre_auth_req(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) |
| { |
| int buf_consumed = false; |
| tpPESession session; |
| uint8_t session_id; |
| tpSirFTPreAuthReq ft_pre_auth_req = (tSirFTPreAuthReq *) msg->bodyptr; |
| |
| if (NULL == ft_pre_auth_req) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log(mac_ctx, LOGE, FL("tSirFTPreAuthReq is NULL"));) |
| #endif |
| return buf_consumed; |
| } |
| |
| /* Get the current session entry */ |
| session = pe_find_session_by_bssid(mac_ctx, |
| ft_pre_auth_req->currbssId, |
| &session_id); |
| if (session == NULL) { |
| lim_log(mac_ctx, LOGE, |
| FL("Unable to find session for the bssid" |
| MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(ft_pre_auth_req->currbssId)); |
| /* Post the FT Pre Auth Response to SME */ |
| lim_post_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0, |
| session); |
| /* |
| * return FALSE, since the Pre-Auth Req will be freed in |
| * limPostFTPreAuthRsp on failure |
| */ |
| return buf_consumed; |
| } |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(session)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(mac_ctx, LOGE, FL("session is not in STA mode")); |
| #endif |
| buf_consumed = true; |
| return buf_consumed; |
| } |
| |
| /* Can set it only after sending auth */ |
| session->ftPEContext.ftPreAuthStatus = eSIR_FAILURE; |
| session->ftPEContext.ftPreAuthSession = true; |
| |
| /* Indicate that this is the session on which preauth is being done */ |
| if (session->ftPEContext.pFTPreAuthReq) { |
| if (session->ftPEContext.pFTPreAuthReq->pbssDescription) { |
| cdf_mem_free( |
| session->ftPEContext.pFTPreAuthReq->pbssDescription); |
| session->ftPEContext.pFTPreAuthReq->pbssDescription = |
| NULL; |
| } |
| cdf_mem_free(session->ftPEContext.pFTPreAuthReq); |
| session->ftPEContext.pFTPreAuthReq = NULL; |
| } |
| |
| /* We need information from the Pre-Auth Req. Lets save that */ |
| session->ftPEContext.pFTPreAuthReq = ft_pre_auth_req; |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(mac_ctx, LOG1, FL("PRE Auth ft_ies_length=%02x%02x%02x"), |
| session->ftPEContext.pFTPreAuthReq->ft_ies[0], |
| session->ftPEContext.pFTPreAuthReq->ft_ies[1], |
| session->ftPEContext.pFTPreAuthReq->ft_ies[2]); |
| #endif |
| #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ |
| lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT, |
| session, 0, 0); |
| #endif |
| |
| /* Dont need to suspend if APs are in same channel */ |
| if (session->currentOperChannel != |
| session->ftPEContext.pFTPreAuthReq->preAuthchannelNum) { |
| /* Need to suspend link only if the channels are different */ |
| lim_log(mac_ctx, LOG2, |
| FL("Performing pre-auth on diff channel(session %p)"), |
| session); |
| lim_ft_pre_auth_suspend_link_handler(mac_ctx, CDF_STATUS_SUCCESS, |
| (uint32_t *)session); |
| } else { |
| lim_log(mac_ctx, LOG2, |
| FL("Performing pre-auth on same channel (session %p)"), |
| session); |
| /* We are in the same channel. Perform pre-auth */ |
| lim_perform_ft_pre_auth(mac_ctx, CDF_STATUS_SUCCESS, NULL, |
| session); |
| } |
| |
| return buf_consumed; |
| } |
| |
| /*------------------------------------------------------------------ |
| * Send the Auth1 |
| * Receive back Auth2 |
| *------------------------------------------------------------------*/ |
| void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, CDF_STATUS status, |
| uint32_t *data, tpPESession psessionEntry) |
| { |
| tSirMacAuthFrameBody authFrame; |
| |
| if (NULL == psessionEntry) { |
| PELOGE(lim_log(pMac, LOGE, FL("psessionEntry is NULL"));) |
| return; |
| } |
| |
| if (psessionEntry->is11Rconnection && |
| psessionEntry->ftPEContext.pFTPreAuthReq) { |
| /* Only 11r assoc has FT IEs */ |
| if (psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies == NULL) { |
| PELOGE(lim_log(pMac, LOGE, |
| "%s: FTIEs for Auth Req Seq 1 is absent", |
| __func__); |
| ) |
| goto preauth_fail; |
| } |
| } |
| |
| if (status != CDF_STATUS_SUCCESS) { |
| PELOGE(lim_log(pMac, LOGE, |
| "%s: Change channel not successful for FT pre-auth", |
| __func__); |
| ) |
| goto preauth_fail; |
| } |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return; |
| } |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOG2(lim_log(pMac, LOG2, "Entered wait auth2 state for FT" |
| " (old session %p)", psessionEntry); |
| ) |
| #endif |
| if (psessionEntry->is11Rconnection) { |
| /* Now we are on the right channel and need to send out Auth1 and |
| * receive Auth2 |
| */ |
| authFrame.authAlgoNumber = eSIR_FT_AUTH; |
| } |
| #if defined FEATURE_WLAN_ESE || defined FEATURE_WLAN_LFR |
| else { |
| /* Will need to make isESEconnection a enum may be for further |
| * improvements to this to match this algorithm number |
| */ |
| authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM; |
| } |
| #endif |
| authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; |
| authFrame.authStatusCode = 0; |
| |
| /* Start timer here to come back to operating channel */ |
| pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId = |
| psessionEntry->peSessionId; |
| if (TX_SUCCESS != |
| tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log(pMac, LOGE, FL("FT Auth Rsp Timer Start Failed"));) |
| #endif |
| } |
| MTRACE(mac_trace |
| (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, |
| eLIM_FT_PREAUTH_RSP_TIMER)); |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOG1(lim_log(pMac, LOG1, FL("FT Auth Rsp Timer Started"));) |
| #endif |
| #ifdef FEATURE_WLAN_DIAG_SUPPORT |
| lim_diag_event_report(pMac, WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, |
| pMac->lim.pSessionEntry, eSIR_SUCCESS, eSIR_SUCCESS); |
| #endif |
| |
| lim_send_auth_mgmt_frame(pMac, &authFrame, |
| psessionEntry->ftPEContext.pFTPreAuthReq-> |
| preAuthbssId, LIM_NO_WEP_IN_FC, psessionEntry); |
| |
| return; |
| |
| preauth_fail: |
| lim_handle_ft_pre_auth_rsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); |
| return; |
| } |
| |
| /*------------------------------------------------------------------ |
| * |
| * Create the new Add Bss Req to the new AP. |
| * This will be used when we are ready to FT to the new AP. |
| * The newly created ft Session entry is passed to this function |
| * |
| *------------------------------------------------------------------*/ |
| tSirRetStatus lim_ft_prepare_add_bss_req(tpAniSirGlobal pMac, |
| uint8_t updateEntry, |
| tpPESession pftSessionEntry, |
| tpSirBssDescription bssDescription) |
| { |
| tpAddBssParams pAddBssParams = NULL; |
| tAddStaParams *sta_ctx; |
| uint8_t chanWidthSupp = 0; |
| tSchBeaconStruct *pBeaconStruct; |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(pftSessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return eSIR_FAILURE; |
| } |
| |
| pBeaconStruct = cdf_mem_malloc(sizeof(tSchBeaconStruct)); |
| if (NULL == pBeaconStruct) { |
| lim_log(pMac, LOGE, |
| FL("Unable to allocate memory for creating ADD_BSS")); |
| return eSIR_MEM_ALLOC_FAILED; |
| } |
| /* Package SIR_HAL_ADD_BSS_REQ message parameters */ |
| pAddBssParams = cdf_mem_malloc(sizeof(tAddBssParams)); |
| if (NULL == pAddBssParams) { |
| cdf_mem_free(pBeaconStruct); |
| lim_log(pMac, LOGP, |
| FL("Unable to allocate memory for creating ADD_BSS")); |
| return (eSIR_MEM_ALLOC_FAILED); |
| } |
| |
| cdf_mem_set((uint8_t *) pAddBssParams, sizeof(tAddBssParams), 0); |
| |
| lim_extract_ap_capabilities(pMac, (uint8_t *) bssDescription->ieFields, |
| lim_get_ielen_from_bss_description(bssDescription), |
| pBeaconStruct); |
| |
| if (pMac->lim.gLimProtectionControl != |
| WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) |
| lim_decide_sta_protection_on_assoc(pMac, pBeaconStruct, |
| pftSessionEntry); |
| |
| cdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId, |
| sizeof(tSirMacAddr)); |
| |
| /* Fill in tAddBssParams selfMacAddr */ |
| cdf_mem_copy(pAddBssParams->selfMacAddr, pftSessionEntry->selfMacAddr, |
| sizeof(tSirMacAddr)); |
| |
| pAddBssParams->bssType = pftSessionEntry->bssType; |
| pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; |
| |
| pAddBssParams->beaconInterval = bssDescription->beaconInterval; |
| |
| pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; |
| pAddBssParams->updateBss = updateEntry; |
| |
| pAddBssParams->reassocReq = true; |
| |
| pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; |
| pAddBssParams->cfParamSet.cfpPeriod = |
| pBeaconStruct->cfParamSet.cfpPeriod; |
| pAddBssParams->cfParamSet.cfpMaxDuration = |
| pBeaconStruct->cfParamSet.cfpMaxDuration; |
| pAddBssParams->cfParamSet.cfpDurRemaining = |
| pBeaconStruct->cfParamSet.cfpDurRemaining; |
| |
| pAddBssParams->rateSet.numRates = |
| pBeaconStruct->supportedRates.numRates; |
| cdf_mem_copy(pAddBssParams->rateSet.rate, |
| pBeaconStruct->supportedRates.rate, |
| pBeaconStruct->supportedRates.numRates); |
| |
| pAddBssParams->nwType = bssDescription->nwType; |
| |
| pAddBssParams->shortSlotTimeSupported = |
| (uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime; |
| pAddBssParams->llaCoexist = |
| (uint8_t) pftSessionEntry->beaconParams.llaCoexist; |
| pAddBssParams->llbCoexist = |
| (uint8_t) pftSessionEntry->beaconParams.llbCoexist; |
| pAddBssParams->llgCoexist = |
| (uint8_t) pftSessionEntry->beaconParams.llgCoexist; |
| pAddBssParams->ht20Coexist = |
| (uint8_t) pftSessionEntry->beaconParams.ht20Coexist; |
| #ifdef WLAN_FEATURE_11W |
| pAddBssParams->rmfEnabled = pftSessionEntry->limRmfEnabled; |
| #endif |
| |
| /* Use the advertised capabilities from the received beacon/PR */ |
| if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && |
| (pBeaconStruct->HTCaps.present)) { |
| pAddBssParams->htCapable = pBeaconStruct->HTCaps.present; |
| cdf_mem_copy(&pAddBssParams->staContext.capab_info, |
| &pBeaconStruct->capabilityInfo, |
| sizeof(pAddBssParams->staContext.capab_info)); |
| cdf_mem_copy(&pAddBssParams->staContext.ht_caps, |
| (uint8_t *) &pBeaconStruct->HTCaps + |
| sizeof(uint8_t), |
| sizeof(pAddBssParams->staContext.ht_caps)); |
| |
| if (pBeaconStruct->HTInfo.present) { |
| pAddBssParams->htOperMode = |
| (tSirMacHTOperatingMode) pBeaconStruct->HTInfo. |
| opMode; |
| pAddBssParams->dualCTSProtection = |
| (uint8_t) pBeaconStruct->HTInfo.dualCTSProtection; |
| |
| chanWidthSupp = lim_get_ht_capability(pMac, |
| eHT_SUPPORTED_CHANNEL_WIDTH_SET, |
| pftSessionEntry); |
| if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && |
| (chanWidthSupp)) { |
| pAddBssParams->ch_width = (uint8_t) |
| pBeaconStruct->HTInfo.recommendedTxWidthSet; |
| if (pBeaconStruct->HTInfo.secondaryChannelOffset == |
| PHY_DOUBLE_CHANNEL_LOW_PRIMARY) |
| pAddBssParams->ch_center_freq_seg0 = |
| bssDescription->channelId + 2; |
| else if (pBeaconStruct->HTInfo.secondaryChannelOffset == |
| PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) |
| pAddBssParams->ch_center_freq_seg0 = |
| bssDescription->channelId - 2; |
| } else { |
| pAddBssParams->ch_width = CH_WIDTH_20MHZ; |
| pAddBssParams->ch_center_freq_seg0 = 0; |
| } |
| pAddBssParams->llnNonGFCoexist = |
| (uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent; |
| pAddBssParams->fLsigTXOPProtectionFullSupport = |
| (uint8_t) pBeaconStruct->HTInfo. |
| lsigTXOPProtectionFullSupport; |
| pAddBssParams->fRIFSMode = |
| pBeaconStruct->HTInfo.rifsMode; |
| } |
| } |
| |
| pAddBssParams->currentOperChannel = bssDescription->channelId; |
| pftSessionEntry->htSecondaryChannelOffset = |
| pBeaconStruct->HTInfo.secondaryChannelOffset; |
| sta_ctx = &pAddBssParams->staContext; |
| |
| #ifdef WLAN_FEATURE_11AC |
| if (pftSessionEntry->vhtCapability && |
| pftSessionEntry->vhtCapabilityPresentInBeacon) { |
| pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present; |
| if (pBeaconStruct->VHTOperation.chanWidth && chanWidthSupp) { |
| pAddBssParams->ch_width = |
| pBeaconStruct->VHTOperation.chanWidth + 1; |
| pAddBssParams->ch_center_freq_seg0 = |
| pBeaconStruct->VHTOperation.chanCenterFreqSeg1; |
| pAddBssParams->ch_center_freq_seg1 = |
| pBeaconStruct->VHTOperation.chanCenterFreqSeg2; |
| } |
| pAddBssParams->staContext.vht_caps = |
| ((pBeaconStruct->VHTCaps.maxMPDULen << |
| SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | |
| (pBeaconStruct->VHTCaps.supportedChannelWidthSet << |
| SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | |
| (pBeaconStruct->VHTCaps.ldpcCodingCap << |
| SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | |
| (pBeaconStruct->VHTCaps.shortGI80MHz << |
| SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | |
| (pBeaconStruct->VHTCaps.shortGI160and80plus80MHz << |
| SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | |
| (pBeaconStruct->VHTCaps.txSTBC << |
| SIR_MAC_VHT_CAP_TXSTBC) | |
| (pBeaconStruct->VHTCaps.rxSTBC << |
| SIR_MAC_VHT_CAP_RXSTBC) | |
| (pBeaconStruct->VHTCaps.suBeamFormerCap << |
| SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | |
| (pBeaconStruct->VHTCaps.suBeamformeeCap << |
| SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | |
| (pBeaconStruct->VHTCaps.csnofBeamformerAntSup << |
| SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | |
| (pBeaconStruct->VHTCaps.numSoundingDim << |
| SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | |
| (pBeaconStruct->VHTCaps.muBeamformerCap << |
| SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) | |
| (pBeaconStruct->VHTCaps.muBeamformeeCap << |
| SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | |
| (pBeaconStruct->VHTCaps.vhtTXOPPS << |
| SIR_MAC_VHT_CAP_TXOPPS) | |
| (pBeaconStruct->VHTCaps.htcVHTCap << |
| SIR_MAC_VHT_CAP_HTC_CAP) | |
| (pBeaconStruct->VHTCaps.maxAMPDULenExp << |
| SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | |
| (pBeaconStruct->VHTCaps.vhtLinkAdaptCap << |
| SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | |
| (pBeaconStruct->VHTCaps.rxAntPattern << |
| SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | |
| (pBeaconStruct->VHTCaps.txAntPattern << |
| SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | |
| (pBeaconStruct->VHTCaps.reserved1 << |
| SIR_MAC_VHT_CAP_RESERVED2)); |
| } else { |
| pAddBssParams->vhtCapable = 0; |
| } |
| #endif |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(pMac, LOG1, FL("SIR_HAL_ADD_BSS_REQ with channel = %d..."), |
| pAddBssParams->currentOperChannel); |
| #endif |
| |
| /* Populate the STA-related parameters here */ |
| /* Note that the STA here refers to the AP */ |
| { |
| pAddBssParams->staContext.staType = STA_ENTRY_OTHER; |
| |
| cdf_mem_copy(pAddBssParams->staContext.bssId, |
| bssDescription->bssId, sizeof(tSirMacAddr)); |
| pAddBssParams->staContext.listenInterval = |
| bssDescription->beaconInterval; |
| |
| pAddBssParams->staContext.assocId = 0; |
| pAddBssParams->staContext.uAPSD = 0; |
| pAddBssParams->staContext.maxSPLen = 0; |
| pAddBssParams->staContext.shortPreambleSupported = |
| (uint8_t) pBeaconStruct->capabilityInfo.shortPreamble; |
| pAddBssParams->staContext.updateSta = updateEntry; |
| pAddBssParams->staContext.encryptType = |
| pftSessionEntry->encryptType; |
| #ifdef WLAN_FEATURE_11W |
| pAddBssParams->staContext.rmfEnabled = |
| pftSessionEntry->limRmfEnabled; |
| #endif |
| |
| if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && |
| (pBeaconStruct->HTCaps.present)) { |
| pAddBssParams->staContext.us32MaxAmpduDuration = 0; |
| pAddBssParams->staContext.htCapable = 1; |
| pAddBssParams->staContext.greenFieldCapable = |
| (uint8_t) pBeaconStruct->HTCaps.greenField; |
| pAddBssParams->staContext.lsigTxopProtection = |
| (uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection; |
| if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && |
| (chanWidthSupp)) { |
| pAddBssParams->staContext.ch_width = (uint8_t) |
| pBeaconStruct->HTInfo.recommendedTxWidthSet; |
| } else { |
| pAddBssParams->staContext.ch_width = |
| CH_WIDTH_20MHZ; |
| } |
| if (pftSessionEntry->vhtCapability && |
| IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) { |
| pAddBssParams->staContext.vhtCapable = 1; |
| if ((pBeaconStruct->VHTCaps.suBeamFormerCap || |
| pBeaconStruct->VHTCaps.muBeamformerCap) && |
| pftSessionEntry->txBFIniFeatureEnabled) |
| sta_ctx->vhtTxBFCapable |
| = 1; |
| if (pBeaconStruct->VHTCaps.suBeamformeeCap && |
| pftSessionEntry->enable_su_tx_bformer) |
| sta_ctx->enable_su_tx_bformer = 1; |
| } |
| if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) && |
| (chanWidthSupp)) { |
| sta_ctx->ch_width = (uint8_t) |
| pBeaconStruct->HTInfo.recommendedTxWidthSet; |
| if (pAddBssParams->staContext.vhtCapable && |
| pBeaconStruct->VHTOperation.chanWidth) |
| sta_ctx->ch_width = |
| pBeaconStruct->VHTOperation.chanWidth |
| + 1; |
| } else { |
| pAddBssParams->staContext.ch_width = |
| CH_WIDTH_20MHZ; |
| } |
| pAddBssParams->staContext.mimoPS = |
| (tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps. |
| mimoPowerSave; |
| pAddBssParams->staContext.maxAmsduSize = |
| (uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize; |
| pAddBssParams->staContext.maxAmpduDensity = |
| pBeaconStruct->HTCaps.mpduDensity; |
| pAddBssParams->staContext.fDsssCckMode40Mhz = |
| (uint8_t) pBeaconStruct->HTCaps.dsssCckMode40MHz; |
| pAddBssParams->staContext.fShortGI20Mhz = |
| (uint8_t) pBeaconStruct->HTCaps.shortGI20MHz; |
| pAddBssParams->staContext.fShortGI40Mhz = |
| (uint8_t) pBeaconStruct->HTCaps.shortGI40MHz; |
| pAddBssParams->staContext.maxAmpduSize = |
| pBeaconStruct->HTCaps.maxRxAMPDUFactor; |
| |
| if (pBeaconStruct->HTInfo.present) |
| pAddBssParams->staContext.rifsMode = |
| pBeaconStruct->HTInfo.rifsMode; |
| } |
| |
| if ((pftSessionEntry->limWmeEnabled |
| && pBeaconStruct->wmeEdcaPresent) |
| || (pftSessionEntry->limQosEnabled |
| && pBeaconStruct->edcaPresent)) |
| pAddBssParams->staContext.wmmEnabled = 1; |
| else |
| pAddBssParams->staContext.wmmEnabled = 0; |
| |
| pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent; |
| /* For OSEN Connection AP does not advertise RSN or WPA IE |
| * so from the IEs we get from supplicant we get this info |
| * so for FW to transmit EAPOL message 4 we shall set |
| * wpa_rsn |
| */ |
| pAddBssParams->staContext.wpa_rsn |= |
| (pBeaconStruct->wpaPresent << 1); |
| if ((!pAddBssParams->staContext.wpa_rsn) |
| && (pftSessionEntry->isOSENConnection)) |
| pAddBssParams->staContext.wpa_rsn = 1; |
| /* Update the rates */ |
| #ifdef WLAN_FEATURE_11AC |
| lim_populate_peer_rate_set(pMac, |
| &pAddBssParams->staContext. |
| supportedRates, |
| pBeaconStruct->HTCaps.supportedMCSSet, |
| false, pftSessionEntry, |
| &pBeaconStruct->VHTCaps); |
| #else |
| lim_populate_peer_rate_set(pMac, |
| &pAddBssParams->staContext. |
| supportedRates, |
| beaconStruct.HTCaps.supportedMCSSet, |
| false, pftSessionEntry); |
| #endif |
| if (pftSessionEntry->htCapability) { |
| pAddBssParams->staContext.supportedRates.opRateMode = |
| eSTA_11n; |
| if (pftSessionEntry->vhtCapability) |
| pAddBssParams->staContext.supportedRates. |
| opRateMode = eSTA_11ac; |
| } else { |
| if (pftSessionEntry->limRFBand == SIR_BAND_5_GHZ) { |
| pAddBssParams->staContext.supportedRates. |
| opRateMode = eSTA_11a; |
| } else { |
| pAddBssParams->staContext.supportedRates. |
| opRateMode = eSTA_11bg; |
| } |
| } |
| } |
| |
| #if defined WLAN_FEATURE_VOWIFI |
| pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower; |
| #endif |
| |
| #ifdef WLAN_FEATURE_11W |
| if (pftSessionEntry->limRmfEnabled) { |
| pAddBssParams->rmfEnabled = 1; |
| pAddBssParams->staContext.rmfEnabled = 1; |
| } |
| #endif |
| |
| pAddBssParams->status = CDF_STATUS_SUCCESS; |
| pAddBssParams->respReqd = true; |
| |
| pAddBssParams->staContext.sessionId = pftSessionEntry->peSessionId; |
| pAddBssParams->staContext.smesessionId = pftSessionEntry->smeSessionId; |
| 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)); |
| pAddBssParams->halPersona = (uint8_t) pftSessionEntry->pePersona; |
| |
| pftSessionEntry->ftPEContext.pAddBssReq = pAddBssParams; |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(pMac, LOG1, FL("Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap...")); |
| #endif |
| |
| cdf_mem_free(pBeaconStruct); |
| return 0; |
| } |
| |
| /*------------------------------------------------------------------ |
| * |
| * Setup the new session for the pre-auth AP. |
| * Return the newly created session entry. |
| * |
| *------------------------------------------------------------------*/ |
| void lim_fill_ft_session(tpAniSirGlobal pMac, |
| tpSirBssDescription pbssDescription, |
| tpPESession pftSessionEntry, tpPESession psessionEntry) |
| { |
| uint8_t currentBssUapsd; |
| tPowerdBm localPowerConstraint; |
| tPowerdBm regMax; |
| tSchBeaconStruct *pBeaconStruct; |
| uint32_t selfDot11Mode; |
| ePhyChanBondState cbEnabledMode; |
| |
| pBeaconStruct = cdf_mem_malloc(sizeof(tSchBeaconStruct)); |
| if (NULL == pBeaconStruct) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(pMac, LOGE, |
| FL |
| ("Unable to allocate memory for creating lim_fill_ft_session")); |
| #endif |
| return; |
| } |
| |
| /* Retrieve the session that has already been created and update the entry */ |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) |
| lim_print_mac_addr(pMac, pbssDescription->bssId, LOG1); |
| #endif |
| pftSessionEntry->limWmeEnabled = psessionEntry->limWmeEnabled; |
| pftSessionEntry->limQosEnabled = psessionEntry->limQosEnabled; |
| pftSessionEntry->limWsmEnabled = psessionEntry->limWsmEnabled; |
| pftSessionEntry->lim11hEnable = psessionEntry->lim11hEnable; |
| pftSessionEntry->isOSENConnection = psessionEntry->isOSENConnection; |
| |
| /* Fields to be filled later */ |
| pftSessionEntry->pLimJoinReq = NULL; |
| pftSessionEntry->smeSessionId = psessionEntry->smeSessionId; |
| pftSessionEntry->transactionId = 0; |
| |
| lim_extract_ap_capabilities(pMac, (uint8_t *) pbssDescription->ieFields, |
| lim_get_ielen_from_bss_description(pbssDescription), |
| pBeaconStruct); |
| |
| pftSessionEntry->rateSet.numRates = |
| pBeaconStruct->supportedRates.numRates; |
| cdf_mem_copy(pftSessionEntry->rateSet.rate, |
| pBeaconStruct->supportedRates.rate, |
| pBeaconStruct->supportedRates.numRates); |
| |
| pftSessionEntry->extRateSet.numRates = |
| pBeaconStruct->extendedRates.numRates; |
| cdf_mem_copy(pftSessionEntry->extRateSet.rate, |
| pBeaconStruct->extendedRates.rate, |
| pftSessionEntry->extRateSet.numRates); |
| |
| pftSessionEntry->ssId.length = pBeaconStruct->ssId.length; |
| cdf_mem_copy(pftSessionEntry->ssId.ssId, pBeaconStruct->ssId.ssId, |
| pftSessionEntry->ssId.length); |
| |
| wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode); |
| lim_log(pMac, LOG1, FL("selfDot11Mode %d"), selfDot11Mode); |
| pftSessionEntry->dot11mode = selfDot11Mode; |
| pftSessionEntry->vhtCapability = |
| (IS_DOT11_MODE_VHT(pftSessionEntry->dot11mode) |
| && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)); |
| pftSessionEntry->htCapability = |
| (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) |
| && pBeaconStruct->HTCaps.present); |
| |
| /* Copy The channel Id to the session Table */ |
| pftSessionEntry->limReassocChannelId = pbssDescription->channelId; |
| pftSessionEntry->currentOperChannel = pbssDescription->channelId; |
| |
| pftSessionEntry->limRFBand = lim_get_rf_band( |
| pftSessionEntry->currentOperChannel); |
| |
| if (pftSessionEntry->limRFBand == SIR_BAND_2_4_GHZ) { |
| cbEnabledMode = pMac->roam.configParam.channelBondingMode24GHz; |
| } else { |
| cbEnabledMode = pMac->roam.configParam.channelBondingMode5GHz; |
| } |
| pftSessionEntry->htSupportedChannelWidthSet = |
| (pBeaconStruct->HTInfo.present) ? |
| (cbEnabledMode && pBeaconStruct->HTInfo.recommendedTxWidthSet) : 0; |
| pftSessionEntry->htRecommendedTxWidthSet = |
| pftSessionEntry->htSupportedChannelWidthSet; |
| |
| |
| #ifdef WLAN_FEATURE_11AC |
| if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) && |
| pBeaconStruct->VHTOperation.present && |
| pftSessionEntry->vhtCapability) { |
| pftSessionEntry->vhtCapabilityPresentInBeacon = 1; |
| } else { |
| pftSessionEntry->vhtCapabilityPresentInBeacon = 0; |
| } |
| #endif |
| if (pftSessionEntry->htRecommendedTxWidthSet) { |
| pftSessionEntry->ch_width = CH_WIDTH_40MHZ; |
| if (pftSessionEntry->vhtCapabilityPresentInBeacon && |
| pBeaconStruct->VHTOperation.chanWidth) { |
| pftSessionEntry->ch_width = |
| pBeaconStruct->VHTOperation.chanWidth + 1; |
| pftSessionEntry->ch_center_freq_seg0 = |
| pBeaconStruct->VHTOperation.chanCenterFreqSeg1; |
| pftSessionEntry->ch_center_freq_seg1 = |
| pBeaconStruct->VHTOperation.chanCenterFreqSeg2; |
| } else { |
| if (pBeaconStruct->HTInfo.secondaryChannelOffset == |
| PHY_DOUBLE_CHANNEL_LOW_PRIMARY) |
| pftSessionEntry->ch_center_freq_seg0 = |
| pbssDescription->channelId + 2; |
| else if (pBeaconStruct->HTInfo.secondaryChannelOffset == |
| PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) |
| pftSessionEntry->ch_center_freq_seg0 = |
| pbssDescription->channelId - 2; |
| else |
| lim_log(pMac, LOGE, FL("Invalid sec ch offset")); |
| } |
| } else { |
| pftSessionEntry->ch_width = CH_WIDTH_20MHZ; |
| pftSessionEntry->ch_center_freq_seg0 = 0; |
| pftSessionEntry->ch_center_freq_seg1 = 0; |
| } |
| |
| sir_copy_mac_addr(pftSessionEntry->selfMacAddr, |
| psessionEntry->selfMacAddr); |
| sir_copy_mac_addr(pftSessionEntry->limReAssocbssId, |
| pbssDescription->bssId); |
| sir_copy_mac_addr(pftSessionEntry->prev_ap_bssid, psessionEntry->bssId); |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) |
| lim_print_mac_addr(pMac, pftSessionEntry->limReAssocbssId, LOG1); |
| #endif |
| |
| /* Store beaconInterval */ |
| pftSessionEntry->beaconParams.beaconInterval = |
| pbssDescription->beaconInterval; |
| pftSessionEntry->bssType = psessionEntry->bssType; |
| |
| pftSessionEntry->statypeForBss = STA_ENTRY_PEER; |
| pftSessionEntry->nwType = pbssDescription->nwType; |
| |
| |
| if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) { |
| pftSessionEntry->limSystemRole = eLIM_STA_ROLE; |
| } else if (pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) { |
| pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; |
| } else { |
| /* Throw an error and return and make sure to delete the session. */ |
| lim_log(pMac, LOGE, FL("Invalid bss type")); |
| } |
| |
| pftSessionEntry->limCurrentBssCaps = pbssDescription->capabilityInfo; |
| pftSessionEntry->limReassocBssCaps = pbssDescription->capabilityInfo; |
| if (pMac->roam.configParam.shortSlotTime && |
| SIR_MAC_GET_SHORT_SLOT_TIME(pftSessionEntry->limReassocBssCaps)) { |
| pftSessionEntry->shortSlotTimeSupported = true; |
| } |
| |
| regMax = cfg_get_regulatory_max_transmit_power(pMac, |
| pftSessionEntry-> |
| currentOperChannel); |
| localPowerConstraint = regMax; |
| lim_extract_ap_capability(pMac, (uint8_t *) pbssDescription->ieFields, |
| lim_get_ielen_from_bss_description(pbssDescription), |
| &pftSessionEntry->limCurrentBssQosCaps, |
| &pftSessionEntry->limCurrentBssPropCap, ¤tBssUapsd, |
| &localPowerConstraint, pftSessionEntry); |
| |
| pftSessionEntry->limReassocBssQosCaps = |
| pftSessionEntry->limCurrentBssQosCaps; |
| pftSessionEntry->limReassocBssPropCap = |
| pftSessionEntry->limCurrentBssPropCap; |
| |
| #ifdef WLAN_FEATURE_VOWIFI_11R |
| pftSessionEntry->is11Rconnection = psessionEntry->is11Rconnection; |
| #endif |
| #ifdef FEATURE_WLAN_ESE |
| pftSessionEntry->isESEconnection = psessionEntry->isESEconnection; |
| pftSessionEntry->is_ese_version_ie_present = |
| pBeaconStruct->is_ese_ver_ie_present; |
| #endif |
| #if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) |
| pftSessionEntry->isFastTransitionEnabled = |
| psessionEntry->isFastTransitionEnabled; |
| #endif |
| |
| #ifdef FEATURE_WLAN_LFR |
| pftSessionEntry->isFastRoamIniFeatureEnabled = |
| psessionEntry->isFastRoamIniFeatureEnabled; |
| #endif |
| |
| #ifdef FEATURE_WLAN_ESE |
| pftSessionEntry->maxTxPower = |
| lim_get_max_tx_power(regMax, localPowerConstraint, |
| pMac->roam.configParam.nTxPowerCap); |
| #else |
| pftSessionEntry->maxTxPower = CDF_MIN(regMax, (localPowerConstraint)); |
| #endif |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(pMac, LOG1, |
| FL |
| ("Reg max = %d, local power = %d, ini tx power = %d, max tx = %d"), |
| 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)); |
| |
| pftSessionEntry->encryptType = psessionEntry->encryptType; |
| #ifdef WLAN_FEATURE_11W |
| pftSessionEntry->limRmfEnabled = psessionEntry->limRmfEnabled; |
| #endif |
| |
| cdf_mem_free(pBeaconStruct); |
| } |
| |
| /*------------------------------------------------------------------ |
| * |
| * Setup the session and the add bss req for the pre-auth AP. |
| * |
| *------------------------------------------------------------------*/ |
| tSirRetStatus lim_ft_setup_auth_session(tpAniSirGlobal pMac, |
| tpPESession psessionEntry) |
| { |
| tpPESession pftSessionEntry = NULL; |
| uint8_t sessionId = 0; |
| |
| pftSessionEntry = |
| pe_find_session_by_bssid(pMac, psessionEntry->limReAssocbssId, |
| &sessionId); |
| if (pftSessionEntry == NULL) { |
| PELOGE(lim_log(pMac, LOGE, |
| FL |
| ("Unable to find session for the following bssid")); |
| ) |
| lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOGE); |
| return eSIR_FAILURE; |
| } |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return eSIR_FAILURE; |
| } |
| |
| if (psessionEntry->ftPEContext.pFTPreAuthReq && |
| psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) { |
| lim_fill_ft_session(pMac, |
| psessionEntry->ftPEContext.pFTPreAuthReq-> |
| pbssDescription, pftSessionEntry, |
| psessionEntry); |
| |
| lim_ft_prepare_add_bss_req(pMac, false, pftSessionEntry, |
| psessionEntry->ftPEContext.pFTPreAuthReq-> |
| pbssDescription); |
| } |
| |
| return eSIR_SUCCESS; |
| } |
| |
| /*------------------------------------------------------------------ |
| * Resume Link Call Back |
| *------------------------------------------------------------------*/ |
| void lim_ft_process_pre_auth_result(tpAniSirGlobal pMac, CDF_STATUS status, |
| uint32_t *data) |
| { |
| tpPESession psessionEntry = (tpPESession) data; |
| |
| if (NULL == psessionEntry || |
| NULL == psessionEntry->ftPEContext.pFTPreAuthReq) |
| return; |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return; |
| } |
| |
| if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) { |
| psessionEntry->ftPEContext.ftPreAuthStatus = |
| lim_ft_setup_auth_session(pMac, psessionEntry); |
| } |
| /* Post the FT Pre Auth Response to SME */ |
| lim_post_ft_pre_auth_rsp(pMac, psessionEntry->ftPEContext.ftPreAuthStatus, |
| psessionEntry->ftPEContext.saved_auth_rsp, |
| psessionEntry->ftPEContext.saved_auth_rsp_length, |
| psessionEntry); |
| } |
| |
| /*------------------------------------------------------------------ |
| * Resume Link Call Back |
| *------------------------------------------------------------------*/ |
| void lim_perform_post_ft_pre_auth_and_channel_change(tpAniSirGlobal pMac, |
| CDF_STATUS status, |
| uint32_t *data, |
| tpPESession psessionEntry) |
| { |
| /* Set the resume channel to Any valid channel (invalid) |
| * This will instruct HAL to set it to any previous valid channel. |
| */ |
| pe_set_resume_channel(pMac, 0, 0); |
| lim_ft_process_pre_auth_result(pMac, CDF_STATUS_SUCCESS, |
| (uint32_t *) psessionEntry); |
| } |
| |
| /* |
| * lim_post_ft_pre_auth_rsp() - post ft pre auth response to SME. |
| * |
| * @mac_ctx: global mac ctx |
| * @status: status code to post in auth rsp |
| * @auth_rsp: pointer to auth rsp FT ie |
| * @auth_rsp_length: len of the IE field |
| * @session: pe session |
| * |
| * post pre auth response to SME. |
| * |
| * Return: void |
| */ |
| void lim_post_ft_pre_auth_rsp(tpAniSirGlobal mac_ctx, |
| tSirRetStatus status, |
| uint8_t *auth_rsp, |
| uint16_t auth_rsp_length, |
| tpPESession session) |
| { |
| tpSirFTPreAuthRsp ft_pre_auth_rsp; |
| tSirMsgQ mmh_msg; |
| uint16_t rsp_len = sizeof(tSirFTPreAuthRsp); |
| |
| ft_pre_auth_rsp = (tpSirFTPreAuthRsp) cdf_mem_malloc(rsp_len); |
| if (NULL == ft_pre_auth_rsp) { |
| lim_log(mac_ctx, LOGE, "Failed to allocate memory"); |
| CDF_ASSERT(ft_pre_auth_rsp != NULL); |
| return; |
| } |
| cdf_mem_zero(ft_pre_auth_rsp, rsp_len); |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(mac_ctx, LOG1, FL("Auth Rsp = %p"), ft_pre_auth_rsp); |
| #endif |
| if (session) { |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(session)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(mac_ctx, LOGE, |
| FL("session is not in STA mode")); |
| #endif |
| cdf_mem_free(ft_pre_auth_rsp); |
| return; |
| } |
| ft_pre_auth_rsp->smeSessionId = session->smeSessionId; |
| /* The bssid of the AP we are sending Auth1 to. */ |
| if (session->ftPEContext.pFTPreAuthReq) |
| sir_copy_mac_addr(ft_pre_auth_rsp->preAuthbssId, |
| session->ftPEContext.pFTPreAuthReq->preAuthbssId); |
| } |
| |
| ft_pre_auth_rsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP; |
| ft_pre_auth_rsp->length = (uint16_t) rsp_len; |
| ft_pre_auth_rsp->status = status; |
| |
| /* Attach the auth response now back to SME */ |
| ft_pre_auth_rsp->ft_ies_length = 0; |
| if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) { |
| /* Only 11r assoc has FT IEs */ |
| cdf_mem_copy(ft_pre_auth_rsp->ft_ies, |
| auth_rsp, auth_rsp_length); |
| ft_pre_auth_rsp->ft_ies_length = auth_rsp_length; |
| } |
| |
| if (status != eSIR_SUCCESS) { |
| /* |
| * Ensure that on Pre-Auth failure the cached Pre-Auth Req and |
| * other allocated memory is freed up before returning. |
| */ |
| lim_log(mac_ctx, LOG1, "Pre-Auth Failed, Cleanup!"); |
| lim_ft_cleanup(mac_ctx, session); |
| } |
| |
| mmh_msg.type = ft_pre_auth_rsp->messageType; |
| mmh_msg.bodyptr = ft_pre_auth_rsp; |
| mmh_msg.bodyval = 0; |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(mac_ctx, LOG1, FL("Posted Auth Rsp to SME with status of 0x%x"), |
| status); |
| #endif |
| #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ |
| if (status == eSIR_SUCCESS) |
| lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PREAUTH_DONE, |
| session, status, 0); |
| #endif |
| lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT); |
| } |
| |
| /*------------------------------------------------------------------ |
| * |
| * Send the FT Pre Auth Response to SME whenever we have a status |
| * ready to be sent to SME |
| * |
| * SME will be the one to send it up to the supplicant to receive |
| * FTIEs which will be required for Reassoc Req. |
| * |
| *------------------------------------------------------------------*/ |
| void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac, tSirRetStatus status, |
| uint8_t *auth_rsp, uint16_t auth_rsp_length, |
| tpPESession psessionEntry) |
| { |
| tpPESession pftSessionEntry = NULL; |
| uint8_t sessionId = 0; |
| tpSirBssDescription pbssDescription = NULL; |
| #ifdef FEATURE_WLAN_DIAG_SUPPORT |
| lim_diag_event_report(pMac, WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, |
| psessionEntry, (uint16_t) status, 0); |
| #endif |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return; |
| } |
| |
| /* Save the status of pre-auth */ |
| psessionEntry->ftPEContext.ftPreAuthStatus = status; |
| |
| /* Save the auth rsp, so we can send it to |
| * SME once we resume link |
| */ |
| psessionEntry->ftPEContext.saved_auth_rsp_length = 0; |
| if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) { |
| cdf_mem_copy(psessionEntry->ftPEContext.saved_auth_rsp, |
| auth_rsp, auth_rsp_length); |
| psessionEntry->ftPEContext.saved_auth_rsp_length = |
| auth_rsp_length; |
| } |
| |
| if (!psessionEntry->ftPEContext.pFTPreAuthReq || |
| !psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) { |
| lim_log(pMac, LOGE, |
| FL("pFTPreAuthReq or pbssDescription is NULL")); |
| return; |
| } |
| |
| /* Create FT session for the re-association at this point */ |
| if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) { |
| pbssDescription = |
| psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription; |
| lim_print_mac_addr(pMac, pbssDescription->bssId, LOG1); |
| if ((pftSessionEntry = |
| pe_create_session(pMac, pbssDescription->bssId, |
| &sessionId, pMac->lim.maxStation, |
| psessionEntry->bssType)) == NULL) { |
| lim_log(pMac, LOGE, FL( |
| "Session not created for pre-auth 11R AP")); |
| status = eSIR_FAILURE; |
| psessionEntry->ftPEContext.ftPreAuthStatus = status; |
| goto send_rsp; |
| } |
| pftSessionEntry->peSessionId = sessionId; |
| pftSessionEntry->smeSessionId = psessionEntry->smeSessionId; |
| sir_copy_mac_addr(pftSessionEntry->selfMacAddr, |
| psessionEntry->selfMacAddr); |
| sir_copy_mac_addr(pftSessionEntry->limReAssocbssId, |
| pbssDescription->bssId); |
| pftSessionEntry->bssType = psessionEntry->bssType; |
| |
| if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) { |
| pftSessionEntry->limSystemRole = eLIM_STA_ROLE; |
| } else if (pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) { |
| pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; |
| } else { |
| lim_log(pMac, LOGE, FL("Invalid bss type")); |
| } |
| pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState; |
| cdf_mem_copy(&(pftSessionEntry->htConfig), |
| &(psessionEntry->htConfig), |
| sizeof(psessionEntry->htConfig)); |
| pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; |
| |
| PELOGE(lim_log |
| (pMac, LOG1, "%s:created session (%p) with id = %d", |
| __func__, pftSessionEntry, |
| pftSessionEntry->peSessionId); |
| ) |
| |
| /* Update the ReAssoc BSSID of the current session */ |
| sir_copy_mac_addr(psessionEntry->limReAssocbssId, |
| pbssDescription->bssId); |
| lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOG1); |
| } |
| send_rsp: |
| if (psessionEntry->currentOperChannel != |
| psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum) { |
| /* Need to move to the original AP channel */ |
| lim_change_channel_with_callback(pMac, |
| psessionEntry->currentOperChannel, |
| lim_perform_post_ft_pre_auth_and_channel_change, |
| NULL, psessionEntry); |
| } else { |
| #ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log(pMac, LOG1, |
| "Pre auth on same channel as connected AP channel %d", |
| psessionEntry->ftPEContext.pFTPreAuthReq-> |
| preAuthchannelNum); |
| ) |
| #endif |
| lim_ft_process_pre_auth_result(pMac, status, |
| (uint32_t *) psessionEntry); |
| } |
| } |
| |
| /*------------------------------------------------------------------ |
| * |
| * This function handles the 11R Reassoc Req from SME |
| * |
| *------------------------------------------------------------------*/ |
| void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf, |
| tpPESession psessionEntry) |
| { |
| uint8_t smeSessionId = 0; |
| uint16_t transactionId = 0; |
| uint8_t chanNum = 0; |
| tLimMlmReassocReq *pMlmReassocReq; |
| uint16_t caps; |
| uint32_t val; |
| tSirMsgQ msgQ; |
| tSirRetStatus retCode; |
| uint32_t teleBcnEn = 0; |
| |
| chanNum = psessionEntry->currentOperChannel; |
| lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smeSessionId, |
| &transactionId); |
| psessionEntry->smeSessionId = smeSessionId; |
| psessionEntry->transactionId = transactionId; |
| |
| #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ |
| lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOCIATING, psessionEntry, 0, |
| 0); |
| #endif |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return; |
| } |
| |
| if (NULL == psessionEntry->ftPEContext.pAddBssReq) { |
| lim_log(pMac, LOGE, FL("pAddBssReq is NULL")); |
| return; |
| } |
| pMlmReassocReq = cdf_mem_malloc(sizeof(tLimMlmReassocReq)); |
| if (NULL == pMlmReassocReq) { |
| lim_log(pMac, LOGE, |
| FL("call to AllocateMemory failed for mlmReassocReq")); |
| return; |
| } |
| |
| cdf_mem_copy(pMlmReassocReq->peerMacAddr, |
| psessionEntry->bssId, sizeof(tSirMacAddr)); |
| |
| if (wlan_cfg_get_int(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, |
| (uint32_t *) &pMlmReassocReq->reassocFailureTimeout) |
| != eSIR_SUCCESS) { |
| /** |
| * Could not get ReassocFailureTimeout value |
| * from CFG. Log error. |
| */ |
| lim_log(pMac, LOGE, |
| FL("could not retrieve ReassocFailureTimeout value")); |
| cdf_mem_free(pMlmReassocReq); |
| return; |
| } |
| |
| if (cfg_get_capability_info(pMac, &caps, psessionEntry) != eSIR_SUCCESS) { |
| /** |
| * Could not get Capabilities value |
| * from CFG. Log error. |
| */ |
| lim_log(pMac, LOGE, FL("could not retrieve Capabilities value")); |
| cdf_mem_free(pMlmReassocReq); |
| return; |
| } |
| pMlmReassocReq->capabilityInfo = caps; |
| |
| /* Update PE sessionId */ |
| pMlmReassocReq->sessionId = psessionEntry->peSessionId; |
| |
| /* If telescopic beaconing is enabled, set listen interval |
| to WNI_CFG_TELE_BCN_MAX_LI |
| */ |
| if (wlan_cfg_get_int(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) != |
| eSIR_SUCCESS) { |
| lim_log(pMac, LOGP, |
| FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN")); |
| cdf_mem_free(pMlmReassocReq); |
| return; |
| } |
| |
| if (teleBcnEn) { |
| if (wlan_cfg_get_int(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != |
| eSIR_SUCCESS) { |
| /** |
| * Could not get ListenInterval value |
| * from CFG. Log error. |
| */ |
| lim_log(pMac, LOGE, |
| FL("could not retrieve ListenInterval")); |
| cdf_mem_free(pMlmReassocReq); |
| return; |
| } |
| } else { |
| if (wlan_cfg_get_int(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != |
| eSIR_SUCCESS) { |
| /** |
| * Could not get ListenInterval value |
| * from CFG. Log error. |
| */ |
| lim_log(pMac, LOGE, |
| FL("could not retrieve ListenInterval")); |
| cdf_mem_free(pMlmReassocReq); |
| return; |
| } |
| } |
| if (lim_set_link_state |
| (pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId, |
| psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) { |
| cdf_mem_free(pMlmReassocReq); |
| return; |
| } |
| |
| pMlmReassocReq->listenInterval = (uint16_t) val; |
| psessionEntry->pLimMlmReassocReq = pMlmReassocReq; |
| |
| /* we need to defer the message until we get the response back from HAL */ |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, false); |
| |
| msgQ.type = SIR_HAL_ADD_BSS_REQ; |
| msgQ.reserved = 0; |
| msgQ.bodyptr = psessionEntry->ftPEContext.pAddBssReq; |
| msgQ.bodyval = 0; |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(pMac, LOG1, FL("Sending SIR_HAL_ADD_BSS_REQ...")); |
| #endif |
| MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type)); |
| retCode = wma_post_ctrl_msg(pMac, &msgQ); |
| if (eSIR_SUCCESS != retCode) { |
| cdf_mem_free(psessionEntry->ftPEContext.pAddBssReq); |
| lim_log(pMac, LOGE, |
| FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), |
| retCode); |
| } |
| |
| psessionEntry->ftPEContext.pAddBssReq = NULL; |
| return; |
| } |
| |
| /* |
| * lim_process_ft_preauth_rsp_timeout() - process ft preauth rsp timeout |
| * |
| * @mac_ctx: global mac ctx |
| * |
| * This function is called if preauth response is not received from the AP |
| * within this timeout while FT in progress |
| * |
| * Return: void |
| */ |
| void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal mac_ctx) |
| { |
| tpPESession session; |
| |
| /* |
| * We have failed pre auth. We need to resume link and get back on |
| * home channel |
| */ |
| lim_log(mac_ctx, LOGE, FL("FT Pre-Auth Time Out!!!!")); |
| session = pe_find_session_by_session_id(mac_ctx, |
| mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId); |
| if (NULL == session) { |
| lim_log(mac_ctx, LOGE, |
| FL("Session Does not exist for given sessionID")); |
| return; |
| } |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(session)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| lim_log(mac_ctx, LOGE, FL("session is not in STA mode")); |
| #endif |
| return; |
| } |
| |
| /* Reset the flag to indicate preauth request session */ |
| session->ftPEContext.ftPreAuthSession = false; |
| |
| if (NULL == session->ftPEContext.pFTPreAuthReq) { |
| lim_log(mac_ctx, LOGE, |
| FL("pFTPreAuthReq is NULL. Auth Rsp might already be posted to SME and ftcleanup done! sessionId:%d"), |
| mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId); |
| return; |
| } |
| |
| /* |
| * To handle the race condition where we recieve preauth rsp after |
| * timer has expired. |
| */ |
| if (true == |
| session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) { |
| lim_log(mac_ctx, LOGE, |
| FL("Auth rsp already posted to SME (session %p)"), |
| session); |
| return; |
| } else { |
| /* |
| * Here we are sending preauth rsp with failure state |
| * and which is forwarded to SME. Now, if we receive an preauth |
| * resp from AP with success it would create a FT pesession, but |
| * will be dropped in SME leaving behind the pesession. Mark |
| * Preauth rsp processed so that any rsp from AP is dropped in |
| * lim_process_auth_frame_no_session. |
| */ |
| lim_log(mac_ctx, LOG1, |
| FL("Auth rsp not yet posted to SME (session %p)"), |
| session); |
| session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = true; |
| } |
| |
| /* |
| * Attempted at Pre-Auth and failed. If we are off channel. We need |
| * to get back to home channel |
| */ |
| lim_handle_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0, session); |
| } |
| |
| /*------------------------------------------------------------------ |
| * |
| * This function is called to process the update key request from SME |
| * |
| *------------------------------------------------------------------*/ |
| bool lim_process_ft_update_key(tpAniSirGlobal pMac, uint32_t *pMsgBuf) |
| { |
| tAddBssParams *pAddBssParams; |
| tSirFTUpdateKeyInfo *pKeyInfo; |
| uint32_t val = 0; |
| tpPESession psessionEntry; |
| uint8_t sessionId; |
| |
| /* Sanity Check */ |
| if (pMac == NULL || pMsgBuf == NULL) { |
| return false; |
| } |
| |
| pKeyInfo = (tSirFTUpdateKeyInfo *) pMsgBuf; |
| |
| psessionEntry = pe_find_session_by_bssid(pMac, pKeyInfo->bssId, &sessionId); |
| if (NULL == psessionEntry) { |
| PELOGE(lim_log(pMac, LOGE, |
| "%s: Unable to find session for the following bssid", |
| __func__); |
| ) |
| lim_print_mac_addr(pMac, pKeyInfo->bssId, LOGE); |
| return false; |
| } |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return false; |
| } |
| |
| if (NULL == psessionEntry->ftPEContext.pAddBssReq) { |
| /* AddBss Req is NULL, save the keys to configure them later. */ |
| tpLimMlmSetKeysReq pMlmSetKeysReq = |
| &psessionEntry->ftPEContext.PreAuthKeyInfo. |
| extSetStaKeyParam; |
| |
| cdf_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq)); |
| cdf_mem_copy(pMlmSetKeysReq->peerMacAddr, pKeyInfo->bssId, |
| sizeof(tSirMacAddr)); |
| pMlmSetKeysReq->sessionId = psessionEntry->peSessionId; |
| pMlmSetKeysReq->smesessionId = psessionEntry->smeSessionId; |
| pMlmSetKeysReq->edType = pKeyInfo->keyMaterial.edType; |
| pMlmSetKeysReq->numKeys = pKeyInfo->keyMaterial.numKeys; |
| cdf_mem_copy((uint8_t *) &pMlmSetKeysReq->key, |
| (uint8_t *) &pKeyInfo->keyMaterial.key, |
| sizeof(tSirKeys)); |
| |
| psessionEntry->ftPEContext.PreAuthKeyInfo. |
| extSetStaKeyParamValid = true; |
| |
| lim_log(pMac, LOGE, FL("pAddBssReq is NULL")); |
| |
| if (psessionEntry->ftPEContext.pAddStaReq == NULL) { |
| lim_log(pMac, LOGE, FL("pAddStaReq is NULL")); |
| lim_send_set_sta_key_req(pMac, pMlmSetKeysReq, 0, 0, |
| psessionEntry, false); |
| psessionEntry->ftPEContext.PreAuthKeyInfo. |
| extSetStaKeyParamValid = false; |
| } |
| } else { |
| pAddBssParams = psessionEntry->ftPEContext.pAddBssReq; |
| |
| /* Store the key information in the ADD BSS parameters */ |
| pAddBssParams->extSetStaKeyParamValid = 1; |
| pAddBssParams->extSetStaKeyParam.encType = |
| pKeyInfo->keyMaterial.edType; |
| cdf_mem_copy((uint8_t *) &pAddBssParams->extSetStaKeyParam.key, |
| (uint8_t *) &pKeyInfo->keyMaterial.key, |
| sizeof(tSirKeys)); |
| if (eSIR_SUCCESS != |
| wlan_cfg_get_int(pMac, WNI_CFG_SINGLE_TID_RC, &val)) { |
| lim_log(pMac, LOGP, |
| FL("Unable to read WNI_CFG_SINGLE_TID_RC")); |
| } |
| |
| pAddBssParams->extSetStaKeyParam.singleTidRc = val; |
| PELOG1(lim_log(pMac, LOG1, FL("Key valid %d"), |
| pAddBssParams->extSetStaKeyParamValid, |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| keyLength); |
| ) |
| |
| pAddBssParams->extSetStaKeyParam.staIdx = 0; |
| |
| PELOG1(lim_log(pMac, LOG1, |
| FL("BSSID = " MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pKeyInfo->bssId)); |
| ) |
| |
| sir_copy_mac_addr(pAddBssParams->extSetStaKeyParam.peerMacAddr, |
| pKeyInfo->bssId); |
| |
| pAddBssParams->extSetStaKeyParam.sendRsp = false; |
| |
| if (pAddBssParams->extSetStaKeyParam.key[0].keyLength == 16) { |
| PELOG1(lim_log(pMac, LOG1, |
| FL |
| ("BSS key = %02X-%02X-%02X-%02X-%02X-%02X-%02X- " |
| "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X"), |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[0], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[1], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[2], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[3], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[4], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[5], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[6], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[7], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[8], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[9], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[10], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[11], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[12], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[13], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[14], |
| pAddBssParams->extSetStaKeyParam.key[0]. |
| key[15]); |
| ) |
| } |
| } |
| return true; |
| } |
| |
| void |
| lim_ft_send_aggr_qos_rsp(tpAniSirGlobal pMac, uint8_t rspReqd, |
| tpAggrAddTsParams aggrQosRsp, uint8_t smesessionId) |
| { |
| tpSirAggrQosRsp rsp; |
| int i = 0; |
| if (!rspReqd) { |
| return; |
| } |
| rsp = cdf_mem_malloc(sizeof(tSirAggrQosRsp)); |
| if (NULL == rsp) { |
| lim_log(pMac, LOGP, |
| FL("AllocateMemory failed for tSirAggrQosRsp")); |
| return; |
| } |
| cdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0); |
| rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP; |
| rsp->sessionId = smesessionId; |
| rsp->length = sizeof(*rsp); |
| rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx; |
| for (i = 0; i < SIR_QOS_NUM_AC_MAX; i++) { |
| if ((1 << i) & aggrQosRsp->tspecIdx) { |
| rsp->aggrInfo.aggrRsp[i].status = aggrQosRsp->status[i]; |
| rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i]; |
| } |
| } |
| lim_send_sme_aggr_qos_rsp(pMac, rsp, smesessionId); |
| return; |
| } |
| void lim_process_ft_aggr_qo_s_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg) |
| { |
| tpAggrAddTsParams pAggrQosRspMsg = NULL; |
| tAddTsParams addTsParam = { 0 }; |
| tpDphHashNode pSta = NULL; |
| uint16_t assocId = 0; |
| tSirMacAddr peerMacAddr; |
| uint8_t rspReqd = 1; |
| tpPESession psessionEntry = NULL; |
| int i = 0; |
| PELOG1(lim_log(pMac, LOG1, FL(" Received AGGR_QOS_RSP from HAL"));) |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, true); |
| pAggrQosRspMsg = (tpAggrAddTsParams) (limMsg->bodyptr); |
| if (NULL == pAggrQosRspMsg) { |
| PELOGE(lim_log(pMac, LOGE, FL("NULL pAggrQosRspMsg"));) |
| return; |
| } |
| psessionEntry = |
| pe_find_session_by_session_id(pMac, pAggrQosRspMsg->sessionId); |
| if (NULL == psessionEntry) { |
| PELOGE(lim_log(pMac, LOGE, |
| FL("Cant find session entry for %s"), __func__); |
| ) |
| if (pAggrQosRspMsg != NULL) { |
| cdf_mem_free(pAggrQosRspMsg); |
| } |
| return; |
| } |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| return; |
| } |
| for (i = 0; i < HAL_QOS_NUM_AC_MAX; i++) { |
| if ((((1 << i) & pAggrQosRspMsg->tspecIdx)) && |
| (pAggrQosRspMsg->status[i] != CDF_STATUS_SUCCESS)) { |
| sir_copy_mac_addr(peerMacAddr, psessionEntry->bssId); |
| addTsParam.staIdx = pAggrQosRspMsg->staIdx; |
| addTsParam.sessionId = pAggrQosRspMsg->sessionId; |
| addTsParam.tspec = pAggrQosRspMsg->tspec[i]; |
| addTsParam.tspecIdx = pAggrQosRspMsg->tspecIdx; |
| lim_send_delts_req_action_frame(pMac, peerMacAddr, rspReqd, |
| &addTsParam.tspec.tsinfo, |
| &addTsParam.tspec, |
| psessionEntry); |
| pSta = |
| dph_lookup_assoc_id(pMac, addTsParam.staIdx, &assocId, |
| &psessionEntry->dph.dphHashTable); |
| if (pSta != NULL) { |
| lim_admit_control_delete_ts(pMac, assocId, |
| &addTsParam.tspec. |
| tsinfo, NULL, |
| (uint8_t *) & |
| addTsParam.tspecIdx); |
| } |
| } |
| } |
| lim_ft_send_aggr_qos_rsp(pMac, rspReqd, pAggrQosRspMsg, |
| psessionEntry->smeSessionId); |
| if (pAggrQosRspMsg != NULL) { |
| cdf_mem_free(pAggrQosRspMsg); |
| } |
| return; |
| } |
| tSirRetStatus lim_process_ft_aggr_qos_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf) |
| { |
| tSirMsgQ msg; |
| tSirAggrQosReq *aggrQosReq = (tSirAggrQosReq *) pMsgBuf; |
| tpAggrAddTsParams pAggrAddTsParam; |
| tpPESession psessionEntry = NULL; |
| tpLimTspecInfo tspecInfo; |
| uint8_t ac; |
| tpDphHashNode pSta; |
| uint16_t aid; |
| uint8_t sessionId; |
| int i; |
| |
| pAggrAddTsParam = cdf_mem_malloc(sizeof(tAggrAddTsParams)); |
| if (NULL == pAggrAddTsParam) { |
| PELOGE(lim_log(pMac, LOGE, FL("AllocateMemory() failed"));) |
| return eSIR_MEM_ALLOC_FAILED; |
| } |
| |
| psessionEntry = |
| pe_find_session_by_bssid(pMac, aggrQosReq->bssId, &sessionId); |
| |
| if (psessionEntry == NULL) { |
| PELOGE(lim_log |
| (pMac, LOGE, |
| FL("psession Entry Null for sessionId = %d"), |
| aggrQosReq->sessionId); |
| ) |
| cdf_mem_free(pAggrAddTsParam); |
| return eSIR_FAILURE; |
| } |
| |
| /* Nothing to be done if the session is not in STA mode */ |
| if (!LIM_IS_STA_ROLE(psessionEntry)) { |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| PELOGE(lim_log |
| (pMac, LOGE, FL("psessionEntry is not in STA mode")); |
| ) |
| #endif |
| cdf_mem_free(pAggrAddTsParam); |
| return eSIR_FAILURE; |
| } |
| |
| pSta = dph_lookup_hash_entry(pMac, aggrQosReq->bssId, &aid, |
| &psessionEntry->dph.dphHashTable); |
| if (pSta == NULL) { |
| PELOGE(lim_log(pMac, LOGE, |
| FL |
| ("Station context not found - ignoring AddTsRsp")); |
| ) |
| cdf_mem_free(pAggrAddTsParam); |
| return eSIR_FAILURE; |
| } |
| |
| cdf_mem_set((uint8_t *) pAggrAddTsParam, sizeof(tAggrAddTsParams), 0); |
| pAggrAddTsParam->staIdx = psessionEntry->staId; |
| /* Fill in the sessionId specific to PE */ |
| pAggrAddTsParam->sessionId = sessionId; |
| pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx; |
| |
| for (i = 0; i < HAL_QOS_NUM_AC_MAX; i++) { |
| if (aggrQosReq->aggrInfo.tspecIdx & (1 << i)) { |
| tSirMacTspecIE *pTspec = |
| &aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec; |
| /* Since AddTS response was successful, check for the PSB flag |
| * and directional flag inside the TS Info field. |
| * An AC is trigger enabled AC if the PSB subfield is set to 1 |
| * in the uplink direction. |
| * An AC is delivery enabled AC if the PSB subfield is set to 1 |
| * in the downlink direction. |
| * An AC is trigger and delivery enabled AC if the PSB subfield |
| * is set to 1 in the bi-direction field. |
| */ |
| if (pTspec->tsinfo.traffic.psb == 1) { |
| lim_set_tspec_uapsd_mask_per_session(pMac, |
| psessionEntry, |
| &pTspec-> |
| tsinfo, |
| SET_UAPSD_MASK); |
| } else { |
| lim_set_tspec_uapsd_mask_per_session(pMac, |
| psessionEntry, |
| &pTspec-> |
| tsinfo, |
| CLEAR_UAPSD_MASK); |
| } |
| /* |
| * ADDTS success, so AC is now admitted. |
| * We shall now use the default |
| * EDCA parameters as advertised by AP and |
| * send the updated EDCA params |
| * to HAL. |
| */ |
| ac = upToAc(pTspec->tsinfo.traffic.userPrio); |
| if (pTspec->tsinfo.traffic.direction == |
| SIR_MAC_DIRECTION_UPLINK) { |
| psessionEntry-> |
| gAcAdmitMask |
| [SIR_MAC_DIRECTION_UPLINK] |= |
| (1 << ac); |
| } else if (pTspec->tsinfo.traffic.direction == |
| SIR_MAC_DIRECTION_DNLINK) { |
| psessionEntry-> |
| gAcAdmitMask |
| [SIR_MAC_DIRECTION_DNLINK] |= |
| (1 << ac); |
| } else if (pTspec->tsinfo.traffic.direction == |
| SIR_MAC_DIRECTION_BIDIR) { |
| psessionEntry-> |
| gAcAdmitMask |
| [SIR_MAC_DIRECTION_UPLINK] |= |
| (1 << ac); |
| psessionEntry-> |
| gAcAdmitMask |
| [SIR_MAC_DIRECTION_DNLINK] |= |
| (1 << ac); |
| } |
| lim_set_active_edca_params(pMac, |
| psessionEntry->gLimEdcaParams, |
| psessionEntry); |
| |
| lim_send_edca_params(pMac, |
| psessionEntry->gLimEdcaParamsActive, |
| pSta->bssId); |
| |
| if (eSIR_SUCCESS != |
| lim_tspec_add(pMac, pSta->staAddr, pSta->assocId, |
| pTspec, 0, &tspecInfo)) { |
| PELOGE(lim_log |
| (pMac, LOGE, |
| FL |
| ("Adding entry in lim Tspec Table failed ")); |
| ) |
| pMac->lim.gLimAddtsSent = false; |
| cdf_mem_free(pAggrAddTsParam); |
| return eSIR_FAILURE; |
| } |
| |
| pAggrAddTsParam->tspec[i] = |
| aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec; |
| } |
| } |
| |
| #ifdef WLAN_FEATURE_ROAM_OFFLOAD |
| if (!pMac->roam.configParam.isRoamOffloadEnabled || |
| (pMac->roam.configParam.isRoamOffloadEnabled && |
| !psessionEntry->is11Rconnection)) |
| #endif |
| { |
| msg.type = WMA_AGGR_QOS_REQ; |
| msg.bodyptr = pAggrAddTsParam; |
| msg.bodyval = 0; |
| |
| /* We need to defer any incoming messages until we get a |
| * WMA_AGGR_QOS_RSP from HAL. |
| */ |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, false); |
| MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msg.type)); |
| |
| if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) { |
| PELOGW(lim_log |
| (pMac, LOGW, FL("wma_post_ctrl_msg() failed")); |
| ) |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, true); |
| cdf_mem_free(pAggrAddTsParam); |
| return eSIR_FAILURE; |
| } |
| } |
| #ifdef WLAN_FEATURE_ROAM_OFFLOAD |
| else { |
| /* Implies it is a LFR3.0 based 11r connection |
| * so donot send add ts request to fimware since it |
| * already has the RIC IEs */ |
| |
| /* Send the Aggr QoS response to SME */ |
| lim_ft_send_aggr_qos_rsp(pMac, true, pAggrAddTsParam, |
| psessionEntry->smeSessionId); |
| if (pAggrAddTsParam != NULL) { |
| cdf_mem_free(pAggrAddTsParam); |
| } |
| } |
| #endif |
| |
| return eSIR_SUCCESS; |
| } |
| |
| #endif /* WLAN_FEATURE_VOWIFI_11R */ |