| /* |
| * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. |
| * |
| * 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 parser_api.cc contains the code for parsing |
| * 802.11 messages. |
| * Author: Pierre Vandwalle |
| * Date: 03/18/02 |
| * History:- |
| * Date Modified by Modification Information |
| * -------------------------------------------------------------------- |
| * |
| */ |
| |
| #include "sir_api.h" |
| #include "ani_global.h" |
| #include "parser_api.h" |
| #include "cfg_api.h" |
| #include "lim_utils.h" |
| #include "utils_parser.h" |
| #include "lim_ser_des_utils.h" |
| #include "sch_api.h" |
| #include "wmm_apsd.h" |
| #include "rrm_api.h" |
| |
| #include "cds_regdomain.h" |
| #include "qdf_crypto.h" |
| #include "lim_process_fils.h" |
| #include "wlan_utility.h" |
| #include "wifi_pos_api.h" |
| #include "wlan_mlme_public_struct.h" |
| |
| #define RSN_OUI_SIZE 4 |
| /* ////////////////////////////////////////////////////////////////////// */ |
| void swap_bit_field16(uint16_t in, uint16_t *out) |
| { |
| #ifdef ANI_LITTLE_BIT_ENDIAN |
| *out = in; |
| #else /* Big-Endian... */ |
| *out = ((in & 0x8000) >> 15) | |
| ((in & 0x4000) >> 13) | |
| ((in & 0x2000) >> 11) | |
| ((in & 0x1000) >> 9) | |
| ((in & 0x0800) >> 7) | |
| ((in & 0x0400) >> 5) | |
| ((in & 0x0200) >> 3) | |
| ((in & 0x0100) >> 1) | |
| ((in & 0x0080) << 1) | |
| ((in & 0x0040) << 3) | |
| ((in & 0x0020) << 5) | |
| ((in & 0x0010) << 7) | |
| ((in & 0x0008) << 9) | |
| ((in & 0x0004) << 11) | |
| ((in & 0x0002) << 13) | ((in & 0x0001) << 15); |
| #endif /* ANI_LITTLE_BIT_ENDIAN */ |
| } |
| |
| static inline void __print_wmm_params(tpAniSirGlobal pMac, |
| tDot11fIEWMMParams *pWmm) |
| { |
| pe_debug("WMM Parameters Received:"); |
| pe_debug("BE: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d", |
| pWmm->acbe_aifsn, pWmm->acbe_acm, pWmm->acbe_aci, |
| pWmm->acbe_acwmin, pWmm->acbe_acwmax, pWmm->acbe_txoplimit); |
| |
| pe_debug("BK: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d", |
| pWmm->acbk_aifsn, pWmm->acbk_acm, pWmm->acbk_aci, |
| pWmm->acbk_acwmin, pWmm->acbk_acwmax, pWmm->acbk_txoplimit); |
| |
| pe_debug("VI: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d", |
| pWmm->acvi_aifsn, pWmm->acvi_acm, pWmm->acvi_aci, |
| pWmm->acvi_acwmin, pWmm->acvi_acwmax, pWmm->acvi_txoplimit); |
| |
| pe_debug("VO: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d", |
| pWmm->acvo_aifsn, pWmm->acvo_acm, pWmm->acvo_aci, |
| pWmm->acvo_acwmin, pWmm->acvo_acwmax, pWmm->acvo_txoplimit); |
| |
| return; |
| } |
| |
| /* ////////////////////////////////////////////////////////////////////// */ |
| /* Functions for populating "dot11f" style IEs */ |
| |
| /* return: >= 0, the starting location of the IE in rsnIEdata inside tSirRSNie */ |
| /* < 0, cannot find */ |
| int find_ie_location(tpAniSirGlobal pMac, tpSirRSNie pRsnIe, uint8_t EID) |
| { |
| int idx, ieLen, bytesLeft; |
| int ret_val = -1; |
| |
| /* Here's what's going on: 'rsnIe' looks like this: */ |
| |
| /* typedef struct sSirRSNie */ |
| /* { */ |
| /* uint16_t length; */ |
| /* uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */ |
| /* } tSirRSNie, *tpSirRSNie; */ |
| |
| /* other code records both the WPA & RSN IEs (including their EIDs & */ |
| /* lengths) into the array 'rsnIEdata'. We may have: */ |
| |
| /* With WAPI support, there may be 3 IEs here */ |
| /* It can be only WPA IE, or only RSN IE or only WAPI IE */ |
| /* Or two or all three of them with no particular ordering */ |
| |
| /* The if/then/else statements that follow are here to figure out */ |
| /* whether we have the WPA IE, and where it is if we *do* have it. */ |
| |
| /* Save the first IE length */ |
| ieLen = pRsnIe->rsnIEdata[1] + 2; |
| idx = 0; |
| bytesLeft = pRsnIe->length; |
| |
| while (1) { |
| if (EID == pRsnIe->rsnIEdata[idx]) { |
| /* Found it */ |
| return idx; |
| } else if (EID != pRsnIe->rsnIEdata[idx] && |
| /* & if no more IE, */ |
| bytesLeft <= (uint16_t) (ieLen)) { |
| pe_debug("No IE (%d) in find_ie_location", EID); |
| return ret_val; |
| } |
| bytesLeft -= ieLen; |
| ieLen = pRsnIe->rsnIEdata[idx + 1] + 2; |
| idx += ieLen; |
| } |
| |
| return ret_val; |
| } |
| |
| QDF_STATUS |
| populate_dot11f_capabilities(tpAniSirGlobal pMac, |
| tDot11fFfCapabilities *pDot11f, |
| tpPESession psessionEntry) |
| { |
| uint16_t cfg; |
| QDF_STATUS nSirStatus; |
| |
| nSirStatus = cfg_get_capability_info(pMac, &cfg, psessionEntry); |
| if (QDF_STATUS_SUCCESS != nSirStatus) { |
| pe_err("Failed to retrieve the Capabilities bitfield from CFG status: %d", |
| nSirStatus); |
| return nSirStatus; |
| } |
| |
| swap_bit_field16(cfg, (uint16_t *) pDot11f); |
| |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_capabilities. */ |
| |
| /** |
| * populate_dot_11_f_ext_chann_switch_ann() - Function to populate ECS |
| * @mac_ptr: Pointer to PMAC structure |
| * @dot_11_ptr: ECS element |
| * @session_entry: PE session entry |
| * |
| * This function is used to populate the extended channel switch element |
| * |
| * Return: None |
| */ |
| void populate_dot_11_f_ext_chann_switch_ann(tpAniSirGlobal mac_ptr, |
| tDot11fIEext_chan_switch_ann *dot_11_ptr, |
| tpPESession session_entry) |
| { |
| uint8_t ch_offset; |
| |
| if (session_entry->gLimChannelSwitch.ch_width == CH_WIDTH_80MHZ) |
| ch_offset = BW80; |
| else |
| ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset; |
| |
| dot_11_ptr->switch_mode = session_entry->gLimChannelSwitch.switchMode; |
| dot_11_ptr->new_reg_class = wlan_reg_dmn_get_opclass_from_channel( |
| mac_ptr->scan.countryCodeCurrent, |
| session_entry->gLimChannelSwitch.primaryChannel, |
| ch_offset); |
| dot_11_ptr->new_channel = |
| session_entry->gLimChannelSwitch.primaryChannel; |
| dot_11_ptr->switch_count = |
| session_entry->gLimChannelSwitch.switchCount; |
| dot_11_ptr->present = 1; |
| |
| pe_debug("country:%s chan:%d width:%d reg:%d off:%d", |
| mac_ptr->scan.countryCodeCurrent, |
| session_entry->gLimChannelSwitch.primaryChannel, |
| session_entry->gLimChannelSwitch.ch_width, |
| dot_11_ptr->new_reg_class, |
| session_entry->gLimChannelSwitch.sec_ch_offset); |
| } |
| |
| void |
| populate_dot11f_chan_switch_ann(tpAniSirGlobal pMac, |
| tDot11fIEChanSwitchAnn *pDot11f, |
| tpPESession psessionEntry) |
| { |
| pDot11f->switchMode = psessionEntry->gLimChannelSwitch.switchMode; |
| pDot11f->newChannel = psessionEntry->gLimChannelSwitch.primaryChannel; |
| pDot11f->switchCount = |
| (uint8_t) psessionEntry->gLimChannelSwitch.switchCount; |
| |
| pDot11f->present = 1; |
| } |
| |
| /** |
| * populate_dot11_supp_operating_classes() - Function to populate supported |
| * operating class IE |
| * @mac_ptr: Pointer to PMAC structure |
| * @dot_11_ptr: Operating class element |
| * @session_entry: PE session entry |
| * |
| * Return: None |
| */ |
| void |
| populate_dot11_supp_operating_classes(tpAniSirGlobal mac_ptr, |
| tDot11fIESuppOperatingClasses *dot_11_ptr, |
| tpPESession session_entry) |
| { |
| uint8_t ch_bandwidth; |
| |
| if (session_entry->ch_width == CH_WIDTH_80MHZ) { |
| ch_bandwidth = BW80; |
| } else { |
| switch (session_entry->htSecondaryChannelOffset) { |
| case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: |
| ch_bandwidth = BW40_HIGH_PRIMARY; |
| break; |
| case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: |
| ch_bandwidth = BW40_LOW_PRIMARY; |
| break; |
| default: |
| ch_bandwidth = BW20; |
| break; |
| } |
| } |
| |
| wlan_reg_dmn_get_curr_opclasses(&dot_11_ptr->num_classes, |
| &dot_11_ptr->classes[1]); |
| dot_11_ptr->classes[0] = wlan_reg_dmn_get_opclass_from_channel( |
| mac_ptr->scan.countryCodeCurrent, |
| session_entry->currentOperChannel, |
| ch_bandwidth); |
| dot_11_ptr->num_classes++; |
| dot_11_ptr->present = 1; |
| } |
| |
| void |
| populate_dot11f_chan_switch_wrapper(tpAniSirGlobal pMac, |
| tDot11fIEChannelSwitchWrapper *pDot11f, |
| tpPESession psessionEntry) |
| { |
| const uint8_t *ie_ptr = NULL; |
| |
| /* |
| * The new country subelement is present only when |
| * 1. AP performs Extended Channel switching to new country. |
| * 2. New Operating Class table or a changed set of operating |
| * classes relative to the contents of the country element sent |
| * in the beacons. |
| * |
| * In the current scenario Channel Switch wrapper IE is included |
| * when we a radar is found and the AP does a channel change in |
| * the same regulatory domain(No country change or Operating class |
| * table). So, we do not need to include the New Country IE. |
| * |
| * Transmit Power Envlope Subelement is optional |
| * in Channel Switch Wrapper IE. So, not setting |
| * the TPE subelement. We include only WiderBWChanSwitchAnn. |
| */ |
| pDot11f->present = 1; |
| |
| /* |
| * Add the Wide Channel Bandwidth Sublement. |
| */ |
| pDot11f->WiderBWChanSwitchAnn.newChanWidth = |
| psessionEntry->gLimWiderBWChannelSwitch.newChanWidth; |
| pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq0 = |
| psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0; |
| pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq1 = |
| psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1; |
| pDot11f->WiderBWChanSwitchAnn.present = 1; |
| |
| /* |
| * Add the VHT Transmit power Envelope Sublement. |
| */ |
| ie_ptr = wlan_get_ie_ptr_from_eid( |
| DOT11F_EID_VHT_TRANSMIT_POWER_ENV, |
| psessionEntry->addIeParams.probeRespBCNData_buff, |
| psessionEntry->addIeParams.probeRespBCNDataLen); |
| if (ie_ptr) { |
| /* Ignore EID field */ |
| pDot11f->vht_transmit_power_env.present = 1; |
| pDot11f->vht_transmit_power_env.num_bytes = ie_ptr[1]; |
| qdf_mem_copy(pDot11f->vht_transmit_power_env.bytes, |
| &ie_ptr[2], pDot11f->vht_transmit_power_env.num_bytes); |
| } |
| |
| } |
| |
| #ifdef FEATURE_AP_MCC_CH_AVOIDANCE |
| void |
| populate_dot11f_avoid_channel_ie(tpAniSirGlobal mac_ctx, |
| tDot11fIEQComVendorIE *dot11f, |
| tpPESession pe_session) |
| { |
| if (!pe_session->sap_advertise_avoid_ch_ie) |
| return; |
| |
| dot11f->present = true; |
| dot11f->type = QCOM_VENDOR_IE_MCC_AVOID_CH; |
| dot11f->channel = pe_session->currentOperChannel; |
| } |
| #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ |
| |
| void |
| populate_dot11f_wider_bw_chan_switch_ann(tpAniSirGlobal pMac, |
| tDot11fIEWiderBWChanSwitchAnn *pDot11f, |
| tpPESession psessionEntry) |
| { |
| pDot11f->present = 1; |
| pDot11f->newChanWidth = |
| psessionEntry->gLimWiderBWChannelSwitch.newChanWidth; |
| pDot11f->newCenterChanFreq0 = |
| psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0; |
| pDot11f->newCenterChanFreq1 = |
| psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1; |
| } |
| |
| QDF_STATUS |
| populate_dot11f_country(tpAniSirGlobal pMac, |
| tDot11fIECountry *pDot11f, tpPESession psessionEntry) |
| { |
| uint32_t len, maxlen; |
| uint16_t item; |
| QDF_STATUS nSirStatus; |
| enum band_info rfBand; |
| uint8_t temp[CFG_MAX_STR_LEN], code[3]; |
| |
| if (psessionEntry->lim11dEnabled) { |
| lim_get_rf_band_new(pMac, &rfBand, psessionEntry); |
| if (rfBand == BAND_5G) { |
| item = WNI_CFG_MAX_TX_POWER_5; |
| maxlen = WNI_CFG_MAX_TX_POWER_5_LEN; |
| } else { |
| item = WNI_CFG_MAX_TX_POWER_2_4; |
| maxlen = WNI_CFG_MAX_TX_POWER_2_4_LEN; |
| } |
| |
| CFG_GET_STR(nSirStatus, pMac, item, temp, len, maxlen); |
| |
| if (3 > len) { |
| /* no limit on tx power, cannot include the IE because at least */ |
| /* one (channel,num,tx power) must be present */ |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| wlan_reg_read_current_country(pMac->psoc, code); |
| |
| qdf_mem_copy(pDot11f->country, code, 2); |
| |
| if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) { |
| pe_err("len:%d is out of bounds, resetting", len); |
| len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; |
| } |
| |
| pDot11f->num_triplets = (uint8_t) (len / 3); |
| qdf_mem_copy((uint8_t *) pDot11f->triplets, temp, len); |
| |
| pDot11f->present = 1; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_country. */ |
| |
| /** |
| * populate_dot11f_ds_params() - To populate DS IE params |
| * mac_ctx: Pointer to global mac context |
| * dot11f_param: pointer to DS params IE |
| * channel: channel number |
| * |
| * This routine will populate DS param in management frame like |
| * beacon, probe response, and etc. |
| * |
| * Return: Overall success |
| */ |
| QDF_STATUS |
| populate_dot11f_ds_params(tpAniSirGlobal mac_ctx, |
| tDot11fIEDSParams *dot11f_param, uint8_t channel) |
| { |
| if (IS_24G_CH(channel)) { |
| /* .11b/g mode PHY => Include the DS Parameter Set IE: */ |
| dot11f_param->curr_channel = channel; |
| dot11f_param->present = 1; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| #define SET_AIFSN(aifsn) (((aifsn) < 2) ? 2 : (aifsn)) |
| |
| void |
| populate_dot11f_edca_param_set(tpAniSirGlobal pMac, |
| tDot11fIEEDCAParamSet *pDot11f, |
| tpPESession psessionEntry) |
| { |
| |
| if (psessionEntry->limQosEnabled) { |
| /* change to bitwise operation, after this is fixed in frames. */ |
| pDot11f->qos = |
| (uint8_t) (0xf0 & |
| (psessionEntry->gLimEdcaParamSetCount << 4)); |
| |
| /* Fill each EDCA parameter set in order: be, bk, vi, vo */ |
| pDot11f->acbe_aifsn = |
| (0xf & |
| SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn)); |
| pDot11f->acbe_acm = |
| (0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm); |
| pDot11f->acbe_aci = (0x3 & SIR_MAC_EDCAACI_BESTEFFORT); |
| pDot11f->acbe_acwmin = |
| (0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min); |
| pDot11f->acbe_acwmax = |
| (0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max); |
| pDot11f->acbe_txoplimit = |
| psessionEntry->gLimEdcaParamsBC[0].txoplimit; |
| |
| pDot11f->acbk_aifsn = |
| (0xf & |
| SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn)); |
| pDot11f->acbk_acm = |
| (0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm); |
| pDot11f->acbk_aci = (0x3 & SIR_MAC_EDCAACI_BACKGROUND); |
| pDot11f->acbk_acwmin = |
| (0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min); |
| pDot11f->acbk_acwmax = |
| (0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max); |
| pDot11f->acbk_txoplimit = |
| psessionEntry->gLimEdcaParamsBC[1].txoplimit; |
| |
| pDot11f->acvi_aifsn = |
| (0xf & |
| SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn)); |
| pDot11f->acvi_acm = |
| (0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm); |
| pDot11f->acvi_aci = (0x3 & SIR_MAC_EDCAACI_VIDEO); |
| pDot11f->acvi_acwmin = |
| (0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min); |
| pDot11f->acvi_acwmax = |
| (0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max); |
| pDot11f->acvi_txoplimit = |
| psessionEntry->gLimEdcaParamsBC[2].txoplimit; |
| |
| pDot11f->acvo_aifsn = |
| (0xf & |
| SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn)); |
| pDot11f->acvo_acm = |
| (0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm); |
| pDot11f->acvo_aci = (0x3 & SIR_MAC_EDCAACI_VOICE); |
| pDot11f->acvo_acwmin = |
| (0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min); |
| pDot11f->acvo_acwmax = |
| (0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max); |
| pDot11f->acvo_txoplimit = |
| psessionEntry->gLimEdcaParamsBC[3].txoplimit; |
| |
| pDot11f->present = 1; |
| } |
| |
| } /* End PopluateDot11fEDCAParamSet. */ |
| |
| QDF_STATUS |
| populate_dot11f_erp_info(tpAniSirGlobal pMac, |
| tDot11fIEERPInfo *pDot11f, tpPESession psessionEntry) |
| { |
| QDF_STATUS nSirStatus; |
| uint32_t val; |
| enum band_info rfBand = BAND_UNKNOWN; |
| |
| lim_get_rf_band_new(pMac, &rfBand, psessionEntry); |
| if (BAND_2G == rfBand) { |
| pDot11f->present = 1; |
| |
| val = psessionEntry->cfgProtection.fromllb; |
| if (!val) { |
| pe_err("11B protection not enabled. Not populating ERP IE %d", |
| val); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| if (psessionEntry->gLim11bParams.protectionEnabled) { |
| pDot11f->non_erp_present = 1; |
| pDot11f->use_prot = 1; |
| } |
| |
| if (psessionEntry->gLimOlbcParams.protectionEnabled) { |
| /* FIXME_PROTECTION: we should be setting non_erp present also. */ |
| /* check the test plan first. */ |
| pDot11f->use_prot = 1; |
| } |
| |
| if ((psessionEntry->gLimNoShortParams.numNonShortPreambleSta) |
| || !psessionEntry->beaconParams.fShortPreamble) { |
| pDot11f->barker_preamble = 1; |
| |
| } |
| /* if protection always flag is set, advertise protection enabled */ |
| /* regardless of legacy stations presence */ |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_11G_PROTECTION_ALWAYS, |
| val); |
| |
| if (val) { |
| pDot11f->use_prot = 1; |
| } |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_erp_info. */ |
| |
| QDF_STATUS |
| populate_dot11f_ext_supp_rates(tpAniSirGlobal pMac, uint8_t nChannelNum, |
| tDot11fIEExtSuppRates *pDot11f, |
| tpPESession psessionEntry) |
| { |
| QDF_STATUS nSirStatus; |
| uint32_t nRates = 0; |
| uint8_t rates[SIR_MAC_RATESET_EID_MAX]; |
| |
| /* Use the ext rates present in session entry whenever nChannelNum is set to OPERATIONAL |
| else use the ext supported rate set from CFG, which is fixed and does not change dynamically and is used for |
| sending mgmt frames (lile probe req) which need to go out before any session is present. |
| */ |
| if (POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum) { |
| if (psessionEntry != NULL) { |
| nRates = psessionEntry->extRateSet.numRates; |
| qdf_mem_copy(rates, psessionEntry->extRateSet.rate, |
| nRates); |
| } else { |
| pe_err("no session context exists while populating Operational Rate Set"); |
| } |
| } else if (HIGHEST_24GHZ_CHANNEL_NUM >= nChannelNum) { |
| CFG_GET_STR(nSirStatus, pMac, |
| WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, rates, |
| nRates, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN); |
| } |
| |
| if (0 != nRates) { |
| pDot11f->num_rates = (uint8_t) nRates; |
| qdf_mem_copy(pDot11f->rates, rates, nRates); |
| pDot11f->present = 1; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_ext_supp_rates. */ |
| |
| QDF_STATUS |
| populate_dot11f_ext_supp_rates1(tpAniSirGlobal pMac, |
| uint8_t nChannelNum, |
| tDot11fIEExtSuppRates *pDot11f) |
| { |
| uint32_t nRates; |
| QDF_STATUS nSirStatus; |
| uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES]; |
| |
| if (14 < nChannelNum) { |
| pDot11f->present = 0; |
| return QDF_STATUS_SUCCESS; |
| } |
| /* N.B. I have *no* idea why we're calling 'wlan_cfg_get_str' with an argument */ |
| /* of WNI_CFG_SUPPORTED_RATES_11A here, but that's what was done */ |
| /* previously & I'm afraid to change it! */ |
| CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A, |
| rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES); |
| |
| if (0 != nRates) { |
| pDot11f->num_rates = (uint8_t) nRates; |
| qdf_mem_copy(pDot11f->rates, rates, nRates); |
| pDot11f->present = 1; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } /* populate_dot11f_ext_supp_rates1. */ |
| |
| QDF_STATUS |
| populate_dot11f_ht_caps(tpAniSirGlobal pMac, |
| tpPESession psessionEntry, tDot11fIEHTCaps *pDot11f) |
| { |
| uint32_t nCfgValue, nCfgLen; |
| uint8_t nCfgValue8; |
| QDF_STATUS nSirStatus; |
| tSirMacHTParametersInfo *pHTParametersInfo; |
| uint8_t disable_high_ht_mcs_2x2 = 0; |
| union { |
| uint16_t nCfgValue16; |
| tSirMacExtendedHTCapabilityInfo extHtCapInfo; |
| } uHTCapabilityInfo; |
| |
| tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo; |
| tSirMacASCapabilityInfo *pASCapabilityInfo; |
| struct mlme_ht_capabilities_info *ht_cap_info; |
| |
| ht_cap_info = &pMac->mlme_cfg->ht_caps.ht_cap_info; |
| |
| pDot11f->mimoPowerSave = ht_cap_info->mimo_power_save; |
| pDot11f->greenField = ht_cap_info->green_field; |
| pDot11f->delayedBA = ht_cap_info->delayed_ba; |
| pDot11f->maximalAMSDUsize = ht_cap_info->maximal_amsdu_size; |
| pDot11f->dsssCckMode40MHz = ht_cap_info->dsss_cck_mode_40_mhz; |
| pDot11f->psmp = ht_cap_info->psmp; |
| pDot11f->stbcControlFrame = ht_cap_info->stbc_control_frame; |
| pDot11f->lsigTXOPProtection = ht_cap_info->l_sig_tx_op_protection; |
| |
| /* All sessionized entries will need the check below */ |
| if (psessionEntry == NULL) { /* Only in case of NO session */ |
| pDot11f->supportedChannelWidthSet = |
| ht_cap_info->supported_channel_width_set; |
| pDot11f->advCodingCap = ht_cap_info->adv_coding_cap; |
| pDot11f->txSTBC = ht_cap_info->tx_stbc; |
| pDot11f->rxSTBC = ht_cap_info->rx_stbc; |
| pDot11f->shortGI20MHz = ht_cap_info->short_gi_20_mhz; |
| pDot11f->shortGI40MHz = ht_cap_info->short_gi_40_mhz; |
| } else { |
| pDot11f->advCodingCap = psessionEntry->htConfig.ht_rx_ldpc; |
| pDot11f->supportedChannelWidthSet = |
| psessionEntry->htSupportedChannelWidthSet; |
| pDot11f->txSTBC = psessionEntry->htConfig.ht_tx_stbc; |
| pDot11f->rxSTBC = psessionEntry->htConfig.ht_rx_stbc; |
| pDot11f->shortGI20MHz = psessionEntry->htConfig.ht_sgi20; |
| pDot11f->shortGI40MHz = psessionEntry->htConfig.ht_sgi40; |
| } |
| |
| /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is |
| eHT_CHANNEL_WIDTH_20MHZ */ |
| if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) { |
| pDot11f->shortGI40MHz = 0; |
| } |
| |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_AMPDU_PARAMS, nCfgValue); |
| |
| nCfgValue8 = (uint8_t) nCfgValue; |
| pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8; |
| |
| pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor; |
| pDot11f->mpduDensity = pHTParametersInfo->mpduDensity; |
| pDot11f->reserved1 = pHTParametersInfo->reserved; |
| |
| CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_MCS_SET, |
| pDot11f->supportedMCSSet, nCfgLen, |
| SIZE_OF_SUPPORTED_MCS_SET); |
| |
| if (psessionEntry) { |
| disable_high_ht_mcs_2x2 = |
| pMac->mlme_cfg->rates.disable_high_ht_mcs_2x2; |
| pe_debug("disable HT high MCS INI param[%d]", |
| disable_high_ht_mcs_2x2); |
| if (psessionEntry->nss == NSS_1x1_MODE) { |
| pDot11f->supportedMCSSet[1] = 0; |
| } else if (IS_24G_CH(psessionEntry->currentOperChannel) && |
| disable_high_ht_mcs_2x2 && |
| (psessionEntry->pePersona == QDF_STA_MODE)) { |
| pe_debug("Disabling high HT MCS [%d]", |
| disable_high_ht_mcs_2x2); |
| pDot11f->supportedMCSSet[1] = |
| (pDot11f->supportedMCSSet[1] >> |
| disable_high_ht_mcs_2x2); |
| } |
| } |
| |
| /* If STA mode, session supported NSS > 1 and |
| * SMPS enabled publish HT SMPS IE |
| */ |
| if (psessionEntry && |
| LIM_IS_STA_ROLE(psessionEntry) && |
| (psessionEntry->enableHtSmps) && |
| (!psessionEntry->supported_nss_1x1)) { |
| pe_debug("Add SM power save IE: %d", |
| psessionEntry->htSmpsvalue); |
| pDot11f->mimoPowerSave = psessionEntry->htSmpsvalue; |
| } |
| |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_EXT_HT_CAP_INFO, nCfgValue); |
| |
| uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; |
| |
| pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco; |
| pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime; |
| pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback; |
| |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_TX_BF_CAP, nCfgValue); |
| |
| pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue; |
| pDot11f->txBF = pTxBFCapabilityInfo->txBF; |
| pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding; |
| pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding; |
| pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF; |
| pDot11f->txZLF = pTxBFCapabilityInfo->txZLF; |
| pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF; |
| pDot11f->calibration = pTxBFCapabilityInfo->calibration; |
| pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF; |
| pDot11f->explicitUncompressedSteeringMatrix = |
| pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix; |
| pDot11f->explicitBFCSIFeedback = |
| pTxBFCapabilityInfo->explicitBFCSIFeedback; |
| pDot11f->explicitUncompressedSteeringMatrixFeedback = |
| pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback; |
| pDot11f->explicitCompressedSteeringMatrixFeedback = |
| pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback; |
| pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae; |
| pDot11f->uncompressedSteeringMatrixBFAntennae = |
| pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae; |
| pDot11f->compressedSteeringMatrixBFAntennae = |
| pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae; |
| |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_AS_CAP, nCfgValue); |
| |
| nCfgValue8 = (uint8_t) nCfgValue; |
| |
| pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8; |
| pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection; |
| pDot11f->explicitCSIFeedbackTx = |
| pASCapabilityInfo->explicitCSIFeedbackTx; |
| pDot11f->antennaIndicesFeedbackTx = |
| pASCapabilityInfo->antennaIndicesFeedbackTx; |
| pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback; |
| pDot11f->antennaIndicesFeedback = |
| pASCapabilityInfo->antennaIndicesFeedback; |
| pDot11f->rxAS = pASCapabilityInfo->rxAS; |
| pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs; |
| |
| pDot11f->present = 1; |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_ht_caps. */ |
| |
| void lim_log_vht_cap(tpAniSirGlobal pMac, tDot11fIEVHTCaps *pDot11f) |
| { |
| #ifdef DUMP_MGMT_CNTNTS |
| pe_debug("maxMPDULen (2): %d", pDot11f->maxMPDULen); |
| pe_debug("supportedChannelWidthSet (2): %d", |
| pDot11f->supportedChannelWidthSet); |
| pe_debug("ldpcCodingCap (1): %d", |
| pDot11f->ldpcCodingCap); |
| pe_debug("shortGI80MHz (1): %d", pDot11f->shortGI80MHz); |
| pe_debug("shortGI160and80plus80MHz (1): %d", |
| pDot11f->shortGI160and80plus80MHz); |
| pe_debug("txSTBC (1): %d", pDot11f->txSTBC); |
| pe_debug("rxSTBC (3): %d", pDot11f->rxSTBC); |
| pe_debug("suBeamFormerCap (1): %d", |
| pDot11f->suBeamFormerCap); |
| pe_debug("suBeamformeeCap (1): %d", |
| pDot11f->suBeamformeeCap); |
| pe_debug("csnofBeamformerAntSup (3): %d", |
| pDot11f->csnofBeamformerAntSup); |
| pe_debug("numSoundingDim (3): %d", |
| pDot11f->numSoundingDim); |
| pe_debug("muBeamformerCap (1): %d", |
| pDot11f->muBeamformerCap); |
| pe_debug("muBeamformeeCap (1): %d", |
| pDot11f->muBeamformeeCap); |
| pe_debug("vhtTXOPPS (1): %d", pDot11f->vhtTXOPPS); |
| pe_debug("htcVHTCap (1): %d", pDot11f->htcVHTCap); |
| pe_debug("maxAMPDULenExp (3): %d", |
| pDot11f->maxAMPDULenExp); |
| pe_debug("vhtLinkAdaptCap (2): %d", |
| pDot11f->vhtLinkAdaptCap); |
| pe_debug("rxAntPattern (1): %d", |
| pDot11f->rxAntPattern; |
| pe_debug("txAntPattern (1): %d", |
| pDot11f->txAntPattern); |
| pe_debug("reserved1 (2): %d", pDot11f->reserved1); |
| pe_debug("rxMCSMap (16): %d", pDot11f->rxMCSMap); |
| pe_debug("rxHighSupDataRate (13): %d", |
| pDot11f->rxHighSupDataRate); |
| pe_debug("reserved2(3): %d", pDot11f->reserved2); |
| pe_debug("txMCSMap (16): %d", pDot11f->txMCSMap); |
| pe_debug("txSupDataRate (13): %d"), |
| pDot11f->txSupDataRate; |
| pe_debug("reserved3 (3): %d", pDot11f->reserved3); |
| #endif /* DUMP_MGMT_CNTNTS */ |
| } |
| |
| static void lim_log_vht_operation(tpAniSirGlobal pMac, |
| tDot11fIEVHTOperation *pDot11f) |
| { |
| #ifdef DUMP_MGMT_CNTNTS |
| pe_debug("chanWidth: %d", pDot11f->chanWidth); |
| pe_debug("chanCenterFreqSeg1: %d", |
| pDot11f->chanCenterFreqSeg1); |
| pe_debug("chanCenterFreqSeg2: %d", |
| pDot11f->chanCenterFreqSeg2); |
| pe_debug("basicMCSSet: %d", pDot11f->basicMCSSet); |
| #endif /* DUMP_MGMT_CNTNTS */ |
| } |
| |
| static void lim_log_vht_ext_bss_load(tpAniSirGlobal pMac, |
| tDot11fIEVHTExtBssLoad *pDot11f) |
| { |
| #ifdef DUMP_MGMT_CNTNTS |
| pe_debug("muMIMOCapStaCount: %d", |
| pDot11f->muMIMOCapStaCount); |
| pe_debug("ssUnderUtil: %d", pDot11f->ssUnderUtil); |
| pe_debug("FortyMHzUtil: %d", pDot11f->FortyMHzUtil); |
| pe_debug("EightyMHzUtil: %d", pDot11f->EightyMHzUtil); |
| pe_debug("OneSixtyMHzUtil: %d", |
| pDot11f->OneSixtyMHzUtil); |
| #endif /* DUMP_MGMT_CNTNTS */ |
| } |
| |
| static void lim_log_operating_mode(tpAniSirGlobal pMac, |
| tDot11fIEOperatingMode *pDot11f) |
| { |
| #ifdef DUMP_MGMT_CNTNTS |
| pe_debug("ChanWidth: %d", pDot11f->chanWidth); |
| pe_debug("reserved: %d", pDot11f->reserved); |
| pe_debug("rxNSS: %d", pDot11f->rxNSS); |
| pe_debug("rxNSS Type: %d", pDot11f->rxNSSType); |
| #endif /* DUMP_MGMT_CNTNTS */ |
| } |
| |
| static void lim_log_qos_map_set(tpAniSirGlobal pMac, tSirQosMapSet *pQosMapSet) |
| { |
| uint8_t i; |
| |
| if (pQosMapSet->num_dscp_exceptions > QOS_MAP_MAX_EX) |
| pQosMapSet->num_dscp_exceptions = QOS_MAP_MAX_EX; |
| |
| pe_debug("num of dscp exceptions: %d", |
| pQosMapSet->num_dscp_exceptions); |
| for (i = 0; i < pQosMapSet->num_dscp_exceptions; i++) { |
| pe_debug("dscp value: %d", |
| pQosMapSet->dscp_exceptions[i][0]); |
| pe_debug("User priority value: %d", |
| pQosMapSet->dscp_exceptions[i][1]); |
| } |
| for (i = 0; i < 8; i++) { |
| pe_debug("dscp low for up %d: %d", i, |
| pQosMapSet->dscp_range[i][0]); |
| pe_debug("dscp high for up %d: %d", i, |
| pQosMapSet->dscp_range[i][1]); |
| } |
| } |
| |
| QDF_STATUS |
| populate_dot11f_vht_caps(tpAniSirGlobal pMac, |
| tpPESession psessionEntry, tDot11fIEVHTCaps *pDot11f) |
| { |
| QDF_STATUS nStatus; |
| uint32_t nCfgValue = 0; |
| |
| pDot11f->present = 1; |
| |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_MAX_MPDU_LENGTH, nCfgValue); |
| pDot11f->maxMPDULen = (nCfgValue & 0x0003); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET, |
| nCfgValue); |
| pDot11f->supportedChannelWidthSet = (nCfgValue & 0x0003); |
| |
| nCfgValue = 0; |
| /* With VHT it suffices if we just examine HT */ |
| if (psessionEntry) { |
| if (psessionEntry->htConfig.ht_rx_ldpc) |
| pDot11f->ldpcCodingCap = |
| psessionEntry->vht_config.ldpc_coding; |
| if (psessionEntry->ch_width < CH_WIDTH_80MHZ) { |
| pDot11f->shortGI80MHz = 0; |
| } else { |
| pDot11f->shortGI80MHz = |
| psessionEntry->vht_config.shortgi80; |
| } |
| |
| if (psessionEntry->ch_width < CH_WIDTH_160MHZ) { |
| pDot11f->shortGI160and80plus80MHz = 0; |
| pDot11f->supportedChannelWidthSet = 0; |
| } else { |
| pDot11f->shortGI160and80plus80MHz = |
| psessionEntry->vht_config.shortgi160and80plus80; |
| } |
| |
| if (psessionEntry->htConfig.ht_tx_stbc) |
| pDot11f->txSTBC = psessionEntry->vht_config.tx_stbc; |
| |
| if (psessionEntry->htConfig.ht_rx_stbc) |
| pDot11f->rxSTBC = psessionEntry->vht_config.rx_stbc; |
| |
| pDot11f->suBeamformeeCap = |
| psessionEntry->vht_config.su_beam_formee; |
| if (psessionEntry->vht_config.su_beam_formee) { |
| pDot11f->muBeamformeeCap = |
| psessionEntry->vht_config.mu_beam_formee; |
| pDot11f->csnofBeamformerAntSup = |
| psessionEntry->vht_config.csnof_beamformer_antSup; |
| } else { |
| pDot11f->muBeamformeeCap = 0; |
| } |
| pDot11f->suBeamFormerCap = |
| psessionEntry->vht_config.su_beam_former; |
| |
| pDot11f->vhtTXOPPS = psessionEntry->vht_config.vht_txops; |
| |
| pDot11f->numSoundingDim = |
| psessionEntry->vht_config.num_soundingdim; |
| |
| pDot11f->htcVHTCap = psessionEntry->vht_config.htc_vhtcap; |
| |
| pDot11f->rxAntPattern = psessionEntry->vht_config.rx_antpattern; |
| |
| pDot11f->txAntPattern = psessionEntry->vht_config.tx_antpattern; |
| |
| pDot11f->maxAMPDULenExp = |
| psessionEntry->vht_config.max_ampdu_lenexp; |
| |
| pDot11f->vhtLinkAdaptCap = |
| psessionEntry->vht_config.vht_link_adapt; |
| } else { |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_LDPC_CODING_CAP, |
| nCfgValue); |
| pDot11f->ldpcCodingCap = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SHORT_GI_80MHZ, |
| nCfgValue); |
| pDot11f->shortGI80MHz = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ, |
| nCfgValue); |
| pDot11f->shortGI160and80plus80MHz = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TXSTBC, nCfgValue); |
| pDot11f->txSTBC = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_RXSTBC, nCfgValue); |
| pDot11f->rxSTBC = (nCfgValue & 0x0007); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_SU_BEAMFORMEE_CAP, nCfgValue); |
| pDot11f->suBeamformeeCap = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_MU_BEAMFORMEE_CAP, nCfgValue); |
| pDot11f->muBeamformeeCap = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SU_BEAMFORMER_CAP, |
| nCfgValue); |
| pDot11f->suBeamFormerCap = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, |
| nCfgValue); |
| pDot11f->csnofBeamformerAntSup = (nCfgValue & 0x0007); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_TXOP_PS, |
| nCfgValue); |
| pDot11f->vhtTXOPPS = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS, |
| nCfgValue); |
| pDot11f->numSoundingDim = (nCfgValue & 0x0007); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_HTC_VHTC_CAP, |
| nCfgValue); |
| pDot11f->htcVHTCap = (nCfgValue & 0x0001); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_RX_ANT_PATTERN, |
| nCfgValue); |
| pDot11f->rxAntPattern = nCfgValue; |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_TX_ANT_PATTERN, |
| nCfgValue); |
| pDot11f->txAntPattern = nCfgValue; |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_AMPDU_LEN_EXPONENT, |
| nCfgValue); |
| pDot11f->maxAMPDULenExp = (nCfgValue & 0x0007); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, |
| WNI_CFG_VHT_LINK_ADAPTATION_CAP, |
| nCfgValue); |
| pDot11f->vhtLinkAdaptCap = (nCfgValue & 0x0003); |
| |
| } |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_MU_BEAMFORMER_CAP, nCfgValue); |
| pDot11f->muBeamformerCap = (nCfgValue & 0x0001); |
| |
| pDot11f->reserved1 = 0; |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_RX_MCS_MAP, nCfgValue); |
| pDot11f->rxMCSMap = (nCfgValue & 0x0000FFFF); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE, |
| nCfgValue); |
| pDot11f->rxHighSupDataRate = (nCfgValue & 0x00001FFF); |
| |
| pDot11f->reserved2 = 0; |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TX_MCS_MAP, nCfgValue); |
| pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF); |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE, |
| nCfgValue); |
| pDot11f->txSupDataRate = (nCfgValue & 0x00001FFF); |
| |
| pDot11f->reserved3 = 0; |
| if (psessionEntry) { |
| if (psessionEntry->nss == NSS_1x1_MODE) { |
| pDot11f->txMCSMap |= DISABLE_NSS2_MCS; |
| pDot11f->rxMCSMap |= DISABLE_NSS2_MCS; |
| pDot11f->txSupDataRate = |
| VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; |
| pDot11f->rxHighSupDataRate = |
| VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; |
| if (!psessionEntry->ch_width && |
| !pMac->roam.configParam.enable_vht20_mcs9 && |
| ((pDot11f->txMCSMap & VHT_1x1_MCS_MASK) == |
| VHT_1x1_MCS9_MAP)) { |
| DISABLE_VHT_MCS_9(pDot11f->txMCSMap, |
| NSS_1x1_MODE); |
| DISABLE_VHT_MCS_9(pDot11f->rxMCSMap, |
| NSS_1x1_MODE); |
| } |
| } else { |
| if (!psessionEntry->ch_width && |
| !pMac->roam.configParam.enable_vht20_mcs9 && |
| ((pDot11f->txMCSMap & VHT_2x2_MCS_MASK) == |
| VHT_2x2_MCS9_MAP)) { |
| DISABLE_VHT_MCS_9(pDot11f->txMCSMap, |
| NSS_2x2_MODE); |
| DISABLE_VHT_MCS_9(pDot11f->rxMCSMap, |
| NSS_2x2_MODE); |
| } |
| } |
| } |
| lim_log_vht_cap(pMac, pDot11f); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS |
| populate_dot11f_vht_operation(tpAniSirGlobal pMac, |
| tpPESession psessionEntry, |
| tDot11fIEVHTOperation *pDot11f) |
| { |
| QDF_STATUS nStatus; |
| uint32_t nCfgValue = 0; |
| |
| pDot11f->present = 1; |
| |
| if (psessionEntry->ch_width > CH_WIDTH_40MHZ) { |
| pDot11f->chanWidth = 1; |
| pDot11f->chanCenterFreqSeg1 = |
| psessionEntry->ch_center_freq_seg0; |
| if (psessionEntry->ch_width == CH_WIDTH_80P80MHZ || |
| psessionEntry->ch_width == CH_WIDTH_160MHZ) |
| pDot11f->chanCenterFreqSeg2 = |
| psessionEntry->ch_center_freq_seg1; |
| else |
| pDot11f->chanCenterFreqSeg2 = 0; |
| } else { |
| pDot11f->chanWidth = 0; |
| pDot11f->chanCenterFreqSeg1 = 0; |
| pDot11f->chanCenterFreqSeg2 = 0; |
| } |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_BASIC_MCS_SET, nCfgValue); |
| pDot11f->basicMCSSet = (uint16_t) nCfgValue; |
| |
| lim_log_vht_operation(pMac, pDot11f); |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } |
| |
| QDF_STATUS |
| populate_dot11f_vht_ext_bss_load(tpAniSirGlobal pMac, |
| tDot11fIEVHTExtBssLoad *pDot11f) |
| { |
| QDF_STATUS nStatus; |
| uint32_t nCfgValue = 0; |
| |
| pDot11f->present = 1; |
| |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT, |
| nCfgValue); |
| pDot11f->muMIMOCapStaCount = (uint8_t) nCfgValue; |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SS_UNDER_UTIL, nCfgValue); |
| pDot11f->ssUnderUtil = (uint8_t) nCfgValue; |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_40MHZ_UTILIZATION, nCfgValue); |
| pDot11f->FortyMHzUtil = (uint8_t) nCfgValue; |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_80MHZ_UTILIZATION, nCfgValue); |
| pDot11f->EightyMHzUtil = (uint8_t) nCfgValue; |
| |
| nCfgValue = 0; |
| CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_160MHZ_UTILIZATION, nCfgValue); |
| pDot11f->EightyMHzUtil = (uint8_t) nCfgValue; |
| |
| lim_log_vht_ext_bss_load(pMac, pDot11f); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS |
| populate_dot11f_ext_cap(tpAniSirGlobal pMac, |
| bool isVHTEnabled, tDot11fIEExtCap *pDot11f, |
| tpPESession psessionEntry) |
| { |
| uint32_t val = 0; |
| struct s_ext_cap *p_ext_cap; |
| |
| pDot11f->present = 1; |
| |
| if (!psessionEntry) { |
| pe_debug("11MC - enabled for non-SAP cases"); |
| pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN; |
| } else if (psessionEntry->sap_dot11mc) { |
| pe_debug("11MC support enabled"); |
| pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN; |
| } else { |
| if (eLIM_AP_ROLE != psessionEntry->limSystemRole) { |
| pe_debug("11MC support enabled"); |
| pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN; |
| } else { |
| pe_debug("11MC support disabled"); |
| pDot11f->num_bytes = DOT11F_IE_EXTCAP_MIN_LEN; |
| } |
| } |
| |
| p_ext_cap = (struct s_ext_cap *)pDot11f->bytes; |
| if (isVHTEnabled == true) |
| p_ext_cap->oper_mode_notification = 1; |
| |
| if (wlan_cfg_get_int(pMac, WNI_CFG_RTT3_ENABLE, &val) != |
| QDF_STATUS_SUCCESS) { |
| pe_err("could not retrieve RTT3 Variable from DAT File"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (val) { |
| uint32_t ftm = ucfg_wifi_pos_get_ftm_cap(pMac->psoc); |
| if (!psessionEntry || LIM_IS_STA_ROLE(psessionEntry)) { |
| p_ext_cap->fine_time_meas_initiator = |
| (ftm & WMI_FW_STA_RTT_INITR) ? 1 : 0; |
| p_ext_cap->fine_time_meas_responder = |
| (ftm & WMI_FW_STA_RTT_RESPR) ? 1 : 0; |
| } else if (LIM_IS_AP_ROLE(psessionEntry)) { |
| p_ext_cap->fine_time_meas_initiator = |
| (ftm & WMI_FW_AP_RTT_INITR) ? 1 : 0; |
| p_ext_cap->fine_time_meas_responder = |
| (ftm & WMI_FW_AP_RTT_RESPR) ? 1 : 0; |
| } |
| } |
| #ifdef QCA_HT_2040_COEX |
| if (pMac->roam.configParam.obssEnabled) |
| p_ext_cap->bss_coexist_mgmt_support = 1; |
| #endif |
| p_ext_cap->ext_chan_switch = 1; |
| |
| if (psessionEntry && psessionEntry->enable_bcast_probe_rsp) |
| p_ext_cap->fils_capability = 1; |
| |
| /* Need to calculate the num_bytes based on bits set */ |
| if (pDot11f->present) |
| pDot11f->num_bytes = lim_compute_ext_cap_ie_length(pDot11f); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| void populate_dot11f_qcn_ie(tDot11fIEQCN_IE *pDot11f) |
| { |
| pDot11f->present = 1; |
| pDot11f->version[0] = QCN_IE_VERSION_SUBATTR_ID; |
| pDot11f->version[1] = QCN_IE_VERSION_SUBATTR_DATA_LEN; |
| pDot11f->version[2] = QCN_IE_VERSION_SUPPORTED; |
| pDot11f->version[3] = QCN_IE_SUBVERSION_SUPPORTED; |
| } |
| |
| QDF_STATUS |
| populate_dot11f_operating_mode(tpAniSirGlobal pMac, |
| tDot11fIEOperatingMode *pDot11f, |
| tpPESession psessionEntry) |
| { |
| pDot11f->present = 1; |
| |
| pDot11f->chanWidth = psessionEntry->gLimOperatingMode.chanWidth; |
| pDot11f->rxNSS = psessionEntry->gLimOperatingMode.rxNSS; |
| pDot11f->rxNSSType = psessionEntry->gLimOperatingMode.rxNSSType; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS |
| populate_dot11f_ht_info(tpAniSirGlobal pMac, |
| tDot11fIEHTInfo *pDot11f, tpPESession psessionEntry) |
| { |
| uint32_t nCfgValue, nCfgLen; |
| uint8_t htInfoField1; |
| uint16_t htInfoField2; |
| QDF_STATUS nSirStatus; |
| tSirMacHTInfoField1 *pHTInfoField1; |
| tSirMacHTInfoField2 *pHTInfoField2; |
| union { |
| uint16_t nCfgValue16; |
| tSirMacHTInfoField3 infoField3; |
| } uHTInfoField; |
| union { |
| uint16_t nCfgValue16; |
| tSirMacHTInfoField2 infoField2; |
| } uHTInfoField2 = { |
| 0 |
| }; |
| |
| if (NULL == psessionEntry) { |
| pe_err("Invalid session entry in populate_dot11f_ht_info()"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pDot11f->primaryChannel = psessionEntry->currentOperChannel; |
| |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD1, nCfgValue); |
| |
| htInfoField1 = (uint8_t) nCfgValue; |
| |
| pHTInfoField1 = (tSirMacHTInfoField1 *) &htInfoField1; |
| pHTInfoField1->rifsMode = psessionEntry->beaconParams.fRIFSMode; |
| pHTInfoField1->serviceIntervalGranularity = |
| pMac->lim.gHTServiceIntervalGranularity; |
| |
| pHTInfoField1->secondaryChannelOffset = |
| psessionEntry->htSecondaryChannelOffset; |
| pHTInfoField1->recommendedTxWidthSet = |
| psessionEntry->htRecommendedTxWidthSet; |
| |
| if ((psessionEntry) && LIM_IS_AP_ROLE(psessionEntry)) { |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD2, |
| nCfgValue); |
| |
| uHTInfoField2.nCfgValue16 = nCfgValue & 0xFFFF; /* this is added for fixing CRs on MDM9K platform - 257951, 259577 */ |
| |
| uHTInfoField2.infoField2.opMode = psessionEntry->htOperMode; |
| uHTInfoField2.infoField2.nonGFDevicesPresent = |
| psessionEntry->beaconParams.llnNonGFCoexist; |
| uHTInfoField2.infoField2.obssNonHTStaPresent = psessionEntry->beaconParams.gHTObssMode; /*added for Obss */ |
| |
| uHTInfoField2.infoField2.reserved = 0; |
| |
| } else { |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD2, |
| nCfgValue); |
| |
| htInfoField2 = (uint16_t) nCfgValue; |
| |
| pHTInfoField2 = (tSirMacHTInfoField2 *) &htInfoField2; |
| pHTInfoField2->opMode = pMac->lim.gHTOperMode; |
| pHTInfoField2->nonGFDevicesPresent = |
| pMac->lim.gHTNonGFDevicesPresent; |
| pHTInfoField2->obssNonHTStaPresent = pMac->lim.gHTObssMode; /*added for Obss */ |
| |
| pHTInfoField2->reserved = 0; |
| } |
| |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD3, nCfgValue); |
| |
| uHTInfoField.nCfgValue16 = nCfgValue & 0xFFFF; |
| |
| uHTInfoField.infoField3.basicSTBCMCS = pMac->lim.gHTSTBCBasicMCS; |
| uHTInfoField.infoField3.dualCTSProtection = |
| pMac->lim.gHTDualCTSProtection; |
| uHTInfoField.infoField3.secondaryBeacon = pMac->lim.gHTSecondaryBeacon; |
| uHTInfoField.infoField3.lsigTXOPProtectionFullSupport = |
| psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport; |
| uHTInfoField.infoField3.pcoActive = pMac->lim.gHTPCOActive; |
| uHTInfoField.infoField3.pcoPhase = pMac->lim.gHTPCOPhase; |
| uHTInfoField.infoField3.reserved = 0; |
| |
| pDot11f->secondaryChannelOffset = pHTInfoField1->secondaryChannelOffset; |
| pDot11f->recommendedTxWidthSet = pHTInfoField1->recommendedTxWidthSet; |
| pDot11f->rifsMode = pHTInfoField1->rifsMode; |
| pDot11f->controlledAccessOnly = pHTInfoField1->controlledAccessOnly; |
| pDot11f->serviceIntervalGranularity = |
| pHTInfoField1->serviceIntervalGranularity; |
| |
| pDot11f->opMode = uHTInfoField2.infoField2.opMode; |
| pDot11f->nonGFDevicesPresent = |
| uHTInfoField2.infoField2.nonGFDevicesPresent; |
| pDot11f->obssNonHTStaPresent = |
| uHTInfoField2.infoField2.obssNonHTStaPresent; |
| pDot11f->reserved = uHTInfoField2.infoField2.reserved; |
| |
| pDot11f->basicSTBCMCS = uHTInfoField.infoField3.basicSTBCMCS; |
| pDot11f->dualCTSProtection = uHTInfoField.infoField3.dualCTSProtection; |
| pDot11f->secondaryBeacon = uHTInfoField.infoField3.secondaryBeacon; |
| pDot11f->lsigTXOPProtectionFullSupport = |
| uHTInfoField.infoField3.lsigTXOPProtectionFullSupport; |
| pDot11f->pcoActive = uHTInfoField.infoField3.pcoActive; |
| pDot11f->pcoPhase = uHTInfoField.infoField3.pcoPhase; |
| pDot11f->reserved2 = uHTInfoField.infoField3.reserved; |
| CFG_GET_STR(nSirStatus, pMac, WNI_CFG_BASIC_MCS_SET, |
| pDot11f->basicMCSSet, nCfgLen, SIZE_OF_BASIC_MCS_SET); |
| |
| pDot11f->present = 1; |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_ht_info. */ |
| |
| void |
| populate_dot11f_ibss_params(tpAniSirGlobal pMac, |
| tDot11fIEIBSSParams *pDot11f, |
| tpPESession psessionEntry) |
| { |
| uint32_t val = 0; |
| |
| if (LIM_IS_IBSS_ROLE(psessionEntry)) { |
| if (wlan_cfg_get_int(pMac, |
| WNI_CFG_IBSS_ATIM_WIN_SIZE, |
| &val) != QDF_STATUS_SUCCESS) { |
| pe_err("could not retrieve IBSS ATIM WIN size"); |
| } |
| pDot11f->present = 1; |
| /* ATIM duration is always set to 0 */ |
| pDot11f->atim = val; |
| } |
| |
| } /* End populate_dot11f_ibss_params. */ |
| |
| #ifdef ANI_SUPPORT_11H |
| QDF_STATUS |
| populate_dot11f_measurement_report0(tpAniSirGlobal pMac, |
| tpSirMacMeasReqActionFrame pReq, |
| tDot11fIEMeasurementReport *pDot11f) |
| { |
| pDot11f->token = pReq->measReqIE.measToken; |
| pDot11f->late = 0; |
| pDot11f->incapable = 0; |
| pDot11f->refused = 1; |
| pDot11f->type = SIR_MAC_BASIC_MEASUREMENT_TYPE; |
| |
| pDot11f->present = 1; |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End PopulatedDot11fMeasurementReport0. */ |
| QDF_STATUS |
| populate_dot11f_measurement_report1(tpAniSirGlobal pMac, |
| tpSirMacMeasReqActionFrame pReq, |
| tDot11fIEMeasurementReport *pDot11f) |
| { |
| pDot11f->token = pReq->measReqIE.measToken; |
| pDot11f->late = 0; |
| pDot11f->incapable = 0; |
| pDot11f->refused = 1; |
| pDot11f->type = SIR_MAC_CCA_MEASUREMENT_TYPE; |
| pDot11f->present = 1; |
| return QDF_STATUS_SUCCESS; |
| } /* End PopulatedDot11fMeasurementReport1. */ |
| QDF_STATUS |
| populate_dot11f_measurement_report2(tpAniSirGlobal pMac, |
| tpSirMacMeasReqActionFrame pReq, |
| tDot11fIEMeasurementReport *pDot11f) |
| { |
| pDot11f->token = pReq->measReqIE.measToken; |
| pDot11f->late = 0; |
| pDot11f->incapable = 0; |
| pDot11f->refused = 1; |
| pDot11f->type = SIR_MAC_RPI_MEASUREMENT_TYPE; |
| pDot11f->present = 1; |
| return QDF_STATUS_SUCCESS; |
| } /* End PopulatedDot11fMeasurementReport2. */ |
| #endif |
| |
| void |
| populate_dot11f_power_caps(tpAniSirGlobal pMac, |
| tDot11fIEPowerCaps *pCaps, |
| uint8_t nAssocType, tpPESession psessionEntry) |
| { |
| if (nAssocType == LIM_REASSOC) { |
| pCaps->minTxPower = |
| psessionEntry->pLimReAssocReq->powerCap.minTxPower; |
| pCaps->maxTxPower = |
| psessionEntry->pLimReAssocReq->powerCap.maxTxPower; |
| } else { |
| pCaps->minTxPower = |
| psessionEntry->pLimJoinReq->powerCap.minTxPower; |
| pCaps->maxTxPower = |
| psessionEntry->pLimJoinReq->powerCap.maxTxPower; |
| |
| } |
| |
| pCaps->present = 1; |
| } /* End populate_dot11f_power_caps. */ |
| |
| QDF_STATUS |
| populate_dot11f_power_constraints(tpAniSirGlobal pMac, |
| tDot11fIEPowerConstraints *pDot11f) |
| { |
| uint32_t cfg; |
| QDF_STATUS nSirStatus; |
| |
| CFG_GET_INT(nSirStatus, pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, cfg); |
| |
| pDot11f->localPowerConstraints = (uint8_t) cfg; |
| pDot11f->present = 1; |
| |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_power_constraints. */ |
| |
| void |
| populate_dot11f_qos_caps_ap(tpAniSirGlobal pMac, |
| tDot11fIEQOSCapsAp *pDot11f, tpPESession psessionEntry) |
| { |
| pDot11f->count = psessionEntry->gLimEdcaParamSetCount; |
| pDot11f->reserved = 0; |
| pDot11f->txopreq = 0; |
| pDot11f->qreq = 0; |
| pDot11f->qack = 0; |
| pDot11f->present = 1; |
| } /* End PopulatedDot11fQOSCaps. */ |
| |
| void |
| populate_dot11f_qos_caps_station(tpAniSirGlobal pMac, tpPESession pe_session, |
| tDot11fIEQOSCapsStation *pDot11f) |
| { |
| uint32_t val = 0; |
| |
| if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != |
| QDF_STATUS_SUCCESS) |
| pe_err("could not retrieve Max SP Length"); |
| |
| pDot11f->more_data_ack = 0; |
| pDot11f->max_sp_length = (uint8_t) val; |
| pDot11f->qack = 0; |
| |
| if (pMac->lim.gUapsdEnable) { |
| pDot11f->acbe_uapsd = |
| LIM_UAPSD_GET(ACBE, pe_session->gUapsdPerAcBitmask); |
| pDot11f->acbk_uapsd = |
| LIM_UAPSD_GET(ACBK, pe_session->gUapsdPerAcBitmask); |
| pDot11f->acvi_uapsd = |
| LIM_UAPSD_GET(ACVI, pe_session->gUapsdPerAcBitmask); |
| pDot11f->acvo_uapsd = |
| LIM_UAPSD_GET(ACVO, pe_session->gUapsdPerAcBitmask); |
| } |
| pDot11f->present = 1; |
| } /* End PopulatedDot11fQOSCaps. */ |
| |
| QDF_STATUS |
| populate_dot11f_rsn(tpAniSirGlobal pMac, |
| tpSirRSNie pRsnIe, tDot11fIERSN *pDot11f) |
| { |
| uint32_t status; |
| int idx; |
| |
| if (pRsnIe->length) { |
| idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_RSN); |
| if (0 <= idx) { |
| status = dot11f_unpack_ie_rsn(pMac, pRsnIe->rsnIEdata + idx + 2, /* EID, length */ |
| pRsnIe->rsnIEdata[idx + 1], |
| pDot11f, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Parse failure in Populate Dot11fRSN (0x%08x)", |
| status); |
| return QDF_STATUS_E_FAILURE; |
| } |
| pe_debug("dot11f_unpack_ie_rsn returned 0x%08x in populate_dot11f_rsn", |
| status); |
| } |
| |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_rsn. */ |
| |
| QDF_STATUS populate_dot11f_rsn_opaque(tpAniSirGlobal pMac, |
| tpSirRSNie pRsnIe, |
| tDot11fIERSNOpaque *pDot11f) |
| { |
| int idx; |
| |
| if (pRsnIe->length) { |
| idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_RSN); |
| if (0 <= idx) { |
| pDot11f->present = 1; |
| pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1]; |
| qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2, /* EID, len */ |
| pRsnIe->rsnIEdata[idx + 1]); |
| } |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_rsn_opaque. */ |
| |
| #if defined(FEATURE_WLAN_WAPI) |
| |
| QDF_STATUS |
| populate_dot11f_wapi(tpAniSirGlobal pMac, |
| tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f) |
| { |
| uint32_t status; |
| int idx; |
| |
| if (pRsnIe->length) { |
| idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WAPI); |
| if (0 <= idx) { |
| status = dot11f_unpack_ie_wapi(pMac, pRsnIe->rsnIEdata + idx + 2, /* EID, length */ |
| pRsnIe->rsnIEdata[idx + 1], |
| pDot11f, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Parse failure in populate_dot11f_wapi (0x%08x)", |
| status); |
| return QDF_STATUS_E_FAILURE; |
| } |
| pe_debug("dot11f_unpack_ie_rsn returned 0x%08x in populate_dot11f_wapi", |
| status); |
| } |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_wapi. */ |
| |
| QDF_STATUS populate_dot11f_wapi_opaque(tpAniSirGlobal pMac, |
| tpSirRSNie pRsnIe, |
| tDot11fIEWAPIOpaque *pDot11f) |
| { |
| int idx; |
| |
| if (pRsnIe->length) { |
| idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WAPI); |
| if (0 <= idx) { |
| pDot11f->present = 1; |
| pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1]; |
| qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2, /* EID, len */ |
| pRsnIe->rsnIEdata[idx + 1]); |
| } |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_wapi_opaque. */ |
| |
| #endif /* defined(FEATURE_WLAN_WAPI) */ |
| |
| void |
| populate_dot11f_ssid(tpAniSirGlobal pMac, |
| tSirMacSSid *pInternal, tDot11fIESSID *pDot11f) |
| { |
| pDot11f->present = 1; |
| pDot11f->num_ssid = pInternal->length; |
| if (pInternal->length) { |
| qdf_mem_copy((uint8_t *) pDot11f->ssid, |
| (uint8_t *) &pInternal->ssId, pInternal->length); |
| } |
| } /* End populate_dot11f_ssid. */ |
| |
| QDF_STATUS populate_dot11f_ssid2(tpAniSirGlobal pMac, tDot11fIESSID *pDot11f) |
| { |
| uint32_t nCfg; |
| QDF_STATUS nSirStatus; |
| |
| CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SSID, pDot11f->ssid, nCfg, 32); |
| pDot11f->num_ssid = (uint8_t) nCfg; |
| pDot11f->present = 1; |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_ssid2. */ |
| |
| void |
| populate_dot11f_schedule(tSirMacScheduleIE *pSchedule, |
| tDot11fIESchedule *pDot11f) |
| { |
| pDot11f->aggregation = pSchedule->info.aggregation; |
| pDot11f->tsid = pSchedule->info.tsid; |
| pDot11f->direction = pSchedule->info.direction; |
| pDot11f->reserved = pSchedule->info.rsvd; |
| pDot11f->service_start_time = pSchedule->svcStartTime; |
| pDot11f->service_interval = pSchedule->svcInterval; |
| pDot11f->max_service_dur = pSchedule->maxSvcDuration; |
| pDot11f->spec_interval = pSchedule->specInterval; |
| |
| pDot11f->present = 1; |
| } /* End populate_dot11f_schedule. */ |
| |
| void |
| populate_dot11f_supp_channels(tpAniSirGlobal pMac, |
| tDot11fIESuppChannels *pDot11f, |
| uint8_t nAssocType, tpPESession psessionEntry) |
| { |
| uint8_t i; |
| uint8_t *p; |
| |
| if (nAssocType == LIM_REASSOC) { |
| p = (uint8_t *) psessionEntry->pLimReAssocReq-> |
| supportedChannels.channelList; |
| pDot11f->num_bands = |
| psessionEntry->pLimReAssocReq->supportedChannels.numChnl; |
| } else { |
| p = (uint8_t *) psessionEntry->pLimJoinReq->supportedChannels. |
| channelList; |
| pDot11f->num_bands = |
| psessionEntry->pLimJoinReq->supportedChannels.numChnl; |
| } |
| for (i = 0U; i < pDot11f->num_bands; ++i, ++p) { |
| pDot11f->bands[i][0] = *p; |
| pDot11f->bands[i][1] = 1; |
| } |
| |
| pDot11f->present = 1; |
| |
| } /* End populate_dot11f_supp_channels. */ |
| |
| QDF_STATUS |
| populate_dot11f_supp_rates(tpAniSirGlobal pMac, |
| uint8_t nChannelNum, |
| tDot11fIESuppRates *pDot11f, tpPESession psessionEntry) |
| { |
| QDF_STATUS nSirStatus; |
| uint32_t nRates; |
| uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES]; |
| |
| /* Use the operational rates present in session entry whenever nChannelNum is set to OPERATIONAL |
| else use the supported rate set from CFG, which is fixed and does not change dynamically and is used for |
| sending mgmt frames (lile probe req) which need to go out before any session is present. |
| */ |
| if (POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum) { |
| #if 0 |
| CFG_GET_STR(nSirStatus, pMac, WNI_CFG_OPERATIONAL_RATE_SET, |
| rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES); |
| #endif /* TO SUPPORT BT-AMP */ |
| if (psessionEntry != NULL) { |
| nRates = psessionEntry->rateSet.numRates; |
| qdf_mem_copy(rates, psessionEntry->rateSet.rate, |
| nRates); |
| } else { |
| pe_err("no session context exists while populating Operational Rate Set"); |
| nRates = 0; |
| } |
| } else if (14 >= nChannelNum) { |
| CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11B, |
| rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES); |
| } else { |
| CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A, |
| rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES); |
| } |
| |
| if (0 != nRates) { |
| pDot11f->num_rates = (uint8_t) nRates; |
| qdf_mem_copy(pDot11f->rates, rates, nRates); |
| pDot11f->present = 1; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_supp_rates. */ |
| |
| /** |
| * populate_dot11f_rates_tdls() - populate supported rates and |
| * extended supported rates IE. |
| * @p_mac gloabl - header. |
| * @p_supp_rates - pointer to supported rates IE |
| * @p_ext_supp_rates - pointer to extended supported rates IE |
| * @curr_oper_channel - current operating channel |
| * |
| * This function populates the supported rates and extended supported |
| * rates IE based in the STA capability. If the number of rates |
| * supported is less than MAX_NUM_SUPPORTED_RATES, only supported rates |
| * IE is populated. |
| * |
| * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE |
| * on failure. |
| */ |
| |
| QDF_STATUS |
| populate_dot11f_rates_tdls(tpAniSirGlobal p_mac, |
| tDot11fIESuppRates *p_supp_rates, |
| tDot11fIEExtSuppRates *p_ext_supp_rates, |
| uint8_t curr_oper_channel) |
| { |
| tSirMacRateSet temp_rateset; |
| tSirMacRateSet temp_rateset2; |
| uint32_t val, i; |
| uint32_t self_dot11mode = 0; |
| |
| wlan_cfg_get_int(p_mac, WNI_CFG_DOT11_MODE, &self_dot11mode); |
| |
| /** |
| * Include 11b rates only when the device configured in |
| * auto, 11a/b/g or 11b_only and also if current base |
| * channel is 5 GHz then no need to advertise the 11b rates. |
| * If devices move to 2.4GHz off-channel then they can communicate |
| * in 11g rates i.e. (6, 9, 12, 18, 24, 36 and 54). |
| */ |
| pe_debug("Current operating channel %d self_dot11mode = %d", |
| curr_oper_channel, self_dot11mode); |
| |
| if ((curr_oper_channel <= SIR_11B_CHANNEL_END) && |
| ((self_dot11mode == WNI_CFG_DOT11_MODE_ALL) || |
| (self_dot11mode == WNI_CFG_DOT11_MODE_11A) || |
| (self_dot11mode == WNI_CFG_DOT11_MODE_11AC) || |
| (self_dot11mode == WNI_CFG_DOT11_MODE_11N) || |
| (self_dot11mode == WNI_CFG_DOT11_MODE_11G) || |
| (self_dot11mode == WNI_CFG_DOT11_MODE_11B))) { |
| val = WNI_CFG_SUPPORTED_RATES_11B_LEN; |
| wlan_cfg_get_str(p_mac, WNI_CFG_SUPPORTED_RATES_11B, |
| (uint8_t *)&temp_rateset.rate, &val); |
| temp_rateset.numRates = (uint8_t) val; |
| } else { |
| temp_rateset.numRates = 0; |
| } |
| |
| /* Include 11a rates when the device configured in non-11b mode */ |
| if (!IS_DOT11_MODE_11B(self_dot11mode)) { |
| val = WNI_CFG_SUPPORTED_RATES_11A_LEN; |
| wlan_cfg_get_str(p_mac, WNI_CFG_SUPPORTED_RATES_11A, |
| (uint8_t *)&temp_rateset2.rate, &val); |
| temp_rateset2.numRates = (uint8_t) val; |
| } else { |
| temp_rateset2.numRates = 0; |
| } |
| |
| if ((temp_rateset.numRates + temp_rateset2.numRates) > |
| SIR_MAC_MAX_NUMBER_OF_RATES) { |
| pe_err("more than %d rates in CFG", |
| SIR_MAC_MAX_NUMBER_OF_RATES); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| /** |
| * copy all rates in temp_rateset, |
| * there are SIR_MAC_MAX_NUMBER_OF_RATES rates max |
| */ |
| for (i = 0; i < temp_rateset2.numRates; i++) |
| temp_rateset.rate[i + temp_rateset.numRates] = |
| temp_rateset2.rate[i]; |
| |
| temp_rateset.numRates += temp_rateset2.numRates; |
| |
| if (temp_rateset.numRates <= MAX_NUM_SUPPORTED_RATES) { |
| p_supp_rates->num_rates = temp_rateset.numRates; |
| qdf_mem_copy(p_supp_rates->rates, temp_rateset.rate, |
| p_supp_rates->num_rates); |
| p_supp_rates->present = 1; |
| } else { /* Populate extended capability as well */ |
| p_supp_rates->num_rates = MAX_NUM_SUPPORTED_RATES; |
| qdf_mem_copy(p_supp_rates->rates, temp_rateset.rate, |
| p_supp_rates->num_rates); |
| p_supp_rates->present = 1; |
| |
| p_ext_supp_rates->num_rates = temp_rateset.numRates - |
| MAX_NUM_SUPPORTED_RATES; |
| qdf_mem_copy(p_ext_supp_rates->rates, |
| (uint8_t *)temp_rateset.rate + |
| MAX_NUM_SUPPORTED_RATES, |
| p_ext_supp_rates->num_rates); |
| p_ext_supp_rates->present = 1; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_rates_tdls */ |
| |
| |
| QDF_STATUS |
| populate_dot11f_tpc_report(tpAniSirGlobal pMac, |
| tDot11fIETPCReport *pDot11f, tpPESession psessionEntry) |
| { |
| uint16_t staid; |
| uint8_t tx_power; |
| QDF_STATUS nSirStatus; |
| |
| nSirStatus = lim_get_mgmt_staid(pMac, &staid, psessionEntry); |
| if (QDF_STATUS_SUCCESS != nSirStatus) { |
| pe_err("Failed to get the STAID in Populate Dot11fTPCReport; lim_get_mgmt_staid returned status %d", |
| nSirStatus); |
| return QDF_STATUS_E_FAILURE; |
| } |
| /* FramesToDo: This function was "misplaced" in the move to Gen4_TVM... */ |
| /* txPower = halGetRateToPwrValue( pMac, staid, pMac->lim.gLimCurrentChannelId, isBeacon ); */ |
| tx_power = cfg_get_regulatory_max_transmit_power(pMac, |
| psessionEntry->currentOperChannel); |
| pDot11f->tx_power = tx_power; |
| pDot11f->link_margin = 0; |
| pDot11f->present = 1; |
| |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_tpc_report. */ |
| |
| void populate_dot11f_ts_info(tSirMacTSInfo *pInfo, tDot11fFfTSInfo *pDot11f) |
| { |
| pDot11f->traffic_type = pInfo->traffic.trafficType; |
| pDot11f->tsid = pInfo->traffic.tsid; |
| pDot11f->direction = pInfo->traffic.direction; |
| pDot11f->access_policy = pInfo->traffic.accessPolicy; |
| pDot11f->aggregation = pInfo->traffic.aggregation; |
| pDot11f->psb = pInfo->traffic.psb; |
| pDot11f->user_priority = pInfo->traffic.userPrio; |
| pDot11f->tsinfo_ack_pol = pInfo->traffic.ackPolicy; |
| pDot11f->schedule = pInfo->schedule.schedule; |
| } /* End PopulatedDot11fTSInfo. */ |
| |
| void populate_dot11f_wmm(tpAniSirGlobal pMac, |
| tDot11fIEWMMInfoAp *pInfo, |
| tDot11fIEWMMParams *pParams, |
| tDot11fIEWMMCaps *pCaps, tpPESession psessionEntry) |
| { |
| if (psessionEntry->limWmeEnabled) { |
| if (LIM_IS_IBSS_ROLE(psessionEntry)) { |
| /* if ( ! sirIsPropCapabilityEnabled( pMac, SIR_MAC_PROP_CAPABILITY_WME ) ) */ |
| { |
| populate_dot11f_wmm_info_ap(pMac, pInfo, |
| psessionEntry); |
| } |
| } else { |
| { |
| populate_dot11f_wmm_params(pMac, pParams, |
| psessionEntry); |
| } |
| |
| if (psessionEntry->limWsmEnabled) { |
| populate_dot11f_wmm_caps(pCaps); |
| } |
| } |
| } |
| } /* End populate_dot11f_wmm. */ |
| |
| void populate_dot11f_wmm_caps(tDot11fIEWMMCaps *pCaps) |
| { |
| pCaps->version = SIR_MAC_OUI_VERSION_1; |
| pCaps->qack = 0; |
| pCaps->queue_request = 1; |
| pCaps->txop_request = 0; |
| pCaps->more_ack = 0; |
| pCaps->present = 1; |
| } /* End PopulateDot11fWmmCaps. */ |
| |
| #ifdef FEATURE_WLAN_ESE |
| void populate_dot11f_re_assoc_tspec(tpAniSirGlobal pMac, |
| tDot11fReAssocRequest *pReassoc, |
| tpPESession psessionEntry) |
| { |
| uint8_t numTspecs = 0, idx; |
| tTspecInfo *pTspec = NULL; |
| |
| numTspecs = psessionEntry->pLimReAssocReq->eseTspecInfo.numTspecs; |
| pTspec = &psessionEntry->pLimReAssocReq->eseTspecInfo.tspec[0]; |
| pReassoc->num_WMMTSPEC = numTspecs; |
| if (numTspecs) { |
| for (idx = 0; idx < numTspecs; idx++) { |
| populate_dot11f_wmmtspec(&pTspec->tspec, |
| &pReassoc->WMMTSPEC[idx]); |
| pTspec->tspec.mediumTime = 0; |
| pTspec++; |
| } |
| } |
| } |
| |
| void ese_populate_wmm_tspec(tSirMacTspecIE *source, |
| ese_wmm_tspec_ie *dest) |
| { |
| dest->traffic_type = source->tsinfo.traffic.trafficType; |
| dest->tsid = source->tsinfo.traffic.tsid; |
| dest->direction = source->tsinfo.traffic.direction; |
| dest->access_policy = source->tsinfo.traffic.accessPolicy; |
| dest->aggregation = source->tsinfo.traffic.aggregation; |
| dest->psb = source->tsinfo.traffic.psb; |
| dest->user_priority = source->tsinfo.traffic.userPrio; |
| dest->tsinfo_ack_pol = source->tsinfo.traffic.ackPolicy; |
| dest->burst_size_defn = source->tsinfo.traffic.burstSizeDefn; |
| /* As defined in IEEE 802.11-2007, section 7.3.2.30 |
| * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed |
| */ |
| dest->size = (source->nomMsduSz & SIZE_MASK); |
| dest->fixed = (source->nomMsduSz & FIXED_MASK) ? 1 : 0; |
| dest->max_msdu_size = source->maxMsduSz; |
| dest->min_service_int = source->minSvcInterval; |
| dest->max_service_int = source->maxSvcInterval; |
| dest->inactivity_int = source->inactInterval; |
| dest->suspension_int = source->suspendInterval; |
| dest->service_start_time = source->svcStartTime; |
| dest->min_data_rate = source->minDataRate; |
| dest->mean_data_rate = source->meanDataRate; |
| dest->peak_data_rate = source->peakDataRate; |
| dest->burst_size = source->maxBurstSz; |
| dest->delay_bound = source->delayBound; |
| dest->min_phy_rate = source->minPhyRate; |
| dest->surplus_bw_allowance = source->surplusBw; |
| dest->medium_time = source->mediumTime; |
| } |
| |
| #endif |
| |
| void populate_dot11f_wmm_info_ap(tpAniSirGlobal pMac, tDot11fIEWMMInfoAp *pInfo, |
| tpPESession psessionEntry) |
| { |
| pInfo->version = SIR_MAC_OUI_VERSION_1; |
| |
| /* WMM Specification 3.1.3, 3.2.3 |
| * An IBSS station shall always use its default WMM parameters. |
| */ |
| if (LIM_IS_IBSS_ROLE(psessionEntry)) { |
| pInfo->param_set_count = 0; |
| pInfo->uapsd = 0; |
| } else { |
| pInfo->param_set_count = |
| (0xf & psessionEntry->gLimEdcaParamSetCount); |
| if (LIM_IS_AP_ROLE(psessionEntry)) { |
| pInfo->uapsd = (0x1 & psessionEntry->apUapsdEnable); |
| } else |
| pInfo->uapsd = (0x1 & pMac->lim.gUapsdEnable); |
| } |
| pInfo->present = 1; |
| } |
| |
| void populate_dot11f_wmm_info_station_per_session(tpAniSirGlobal pMac, |
| tpPESession psessionEntry, |
| tDot11fIEWMMInfoStation *pInfo) |
| { |
| uint32_t val = 0; |
| |
| pInfo->version = SIR_MAC_OUI_VERSION_1; |
| pInfo->acvo_uapsd = |
| LIM_UAPSD_GET(ACVO, psessionEntry->gUapsdPerAcBitmask); |
| pInfo->acvi_uapsd = |
| LIM_UAPSD_GET(ACVI, psessionEntry->gUapsdPerAcBitmask); |
| pInfo->acbk_uapsd = |
| LIM_UAPSD_GET(ACBK, psessionEntry->gUapsdPerAcBitmask); |
| pInfo->acbe_uapsd = |
| LIM_UAPSD_GET(ACBE, psessionEntry->gUapsdPerAcBitmask); |
| |
| if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != |
| QDF_STATUS_SUCCESS) |
| pe_err("could not retrieve Max SP Length"); |
| |
| pInfo->max_sp_length = (uint8_t) val; |
| pInfo->present = 1; |
| } |
| |
| void populate_dot11f_wmm_params(tpAniSirGlobal pMac, |
| tDot11fIEWMMParams *pParams, |
| tpPESession psessionEntry) |
| { |
| pParams->version = SIR_MAC_OUI_VERSION_1; |
| |
| if (LIM_IS_AP_ROLE(psessionEntry)) |
| pParams->qosInfo = |
| (psessionEntry-> |
| apUapsdEnable << 7) | ((uint8_t) (0x0f & psessionEntry-> |
| gLimEdcaParamSetCount)); |
| else |
| pParams->qosInfo = |
| (pMac->lim. |
| gUapsdEnable << 7) | ((uint8_t) (0x0f & psessionEntry-> |
| gLimEdcaParamSetCount)); |
| |
| /* Fill each EDCA parameter set in order: be, bk, vi, vo */ |
| pParams->acbe_aifsn = |
| (0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn)); |
| pParams->acbe_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm); |
| pParams->acbe_aci = (0x3 & SIR_MAC_EDCAACI_BESTEFFORT); |
| pParams->acbe_acwmin = |
| (0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min); |
| pParams->acbe_acwmax = |
| (0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max); |
| pParams->acbe_txoplimit = psessionEntry->gLimEdcaParamsBC[0].txoplimit; |
| |
| pParams->acbk_aifsn = |
| (0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn)); |
| pParams->acbk_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm); |
| pParams->acbk_aci = (0x3 & SIR_MAC_EDCAACI_BACKGROUND); |
| pParams->acbk_acwmin = |
| (0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min); |
| pParams->acbk_acwmax = |
| (0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max); |
| pParams->acbk_txoplimit = psessionEntry->gLimEdcaParamsBC[1].txoplimit; |
| |
| if (LIM_IS_AP_ROLE(psessionEntry)) |
| pParams->acvi_aifsn = |
| (0xf & psessionEntry->gLimEdcaParamsBC[2].aci.aifsn); |
| else |
| pParams->acvi_aifsn = |
| (0xf & |
| SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn)); |
| |
| pParams->acvi_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm); |
| pParams->acvi_aci = (0x3 & SIR_MAC_EDCAACI_VIDEO); |
| pParams->acvi_acwmin = |
| (0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min); |
| pParams->acvi_acwmax = |
| (0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max); |
| pParams->acvi_txoplimit = psessionEntry->gLimEdcaParamsBC[2].txoplimit; |
| |
| if (LIM_IS_AP_ROLE(psessionEntry)) |
| pParams->acvo_aifsn = |
| (0xf & psessionEntry->gLimEdcaParamsBC[3].aci.aifsn); |
| else |
| pParams->acvo_aifsn = |
| (0xf & |
| SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn)); |
| |
| pParams->acvo_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm); |
| pParams->acvo_aci = (0x3 & SIR_MAC_EDCAACI_VOICE); |
| pParams->acvo_acwmin = |
| (0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min); |
| pParams->acvo_acwmax = |
| (0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max); |
| pParams->acvo_txoplimit = psessionEntry->gLimEdcaParamsBC[3].txoplimit; |
| |
| pParams->present = 1; |
| |
| } /* End populate_dot11f_wmm_params. */ |
| |
| void populate_dot11f_wmm_schedule(tSirMacScheduleIE *pSchedule, |
| tDot11fIEWMMSchedule *pDot11f) |
| { |
| pDot11f->version = 1; |
| pDot11f->aggregation = pSchedule->info.aggregation; |
| pDot11f->tsid = pSchedule->info.tsid; |
| pDot11f->direction = pSchedule->info.direction; |
| pDot11f->reserved = pSchedule->info.rsvd; |
| pDot11f->service_start_time = pSchedule->svcStartTime; |
| pDot11f->service_interval = pSchedule->svcInterval; |
| pDot11f->max_service_dur = pSchedule->maxSvcDuration; |
| pDot11f->spec_interval = pSchedule->specInterval; |
| |
| pDot11f->present = 1; |
| } /* End populate_dot11f_wmm_schedule. */ |
| |
| QDF_STATUS |
| populate_dot11f_wpa(tpAniSirGlobal pMac, |
| tpSirRSNie pRsnIe, tDot11fIEWPA *pDot11f) |
| { |
| uint32_t status; |
| int idx; |
| |
| if (pRsnIe->length) { |
| idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WPA); |
| if (0 <= idx) { |
| status = dot11f_unpack_ie_wpa(pMac, pRsnIe->rsnIEdata + idx + 2 + 4, /* EID, length, OUI */ |
| pRsnIe->rsnIEdata[idx + 1] - 4, /* OUI */ |
| pDot11f, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Parse failure in Populate Dot11fWPA (0x%08x)", |
| status); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_wpa. */ |
| |
| QDF_STATUS populate_dot11f_wpa_opaque(tpAniSirGlobal pMac, |
| tpSirRSNie pRsnIe, |
| tDot11fIEWPAOpaque *pDot11f) |
| { |
| int idx; |
| |
| if (pRsnIe->length) { |
| idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WPA); |
| if (0 <= idx) { |
| pDot11f->present = 1; |
| pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1] - 4; |
| qdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2 + 4, /* EID, len, OUI */ |
| pRsnIe->rsnIEdata[idx + 1] - 4); /* OUI */ |
| } |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_wpa_opaque. */ |
| |
| /* ////////////////////////////////////////////////////////////////////// */ |
| |
| QDF_STATUS |
| sir_convert_probe_req_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, tpSirProbeReq pProbeReq) |
| { |
| uint32_t status; |
| tDot11fProbeRequest pr; |
| |
| /* Ok, zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pProbeReq, sizeof(tSirProbeReq), 0); |
| |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_probe_request(pMac, pFrame, nFrame, &pr, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse a Probe Request (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking a Probe Request (0x%08x, %d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fProbeRequestto' a 'tSirProbeReq'... */ |
| if (!pr.SSID.present) { |
| pe_debug("Mandatory IE SSID not present!"); |
| } else { |
| pProbeReq->ssidPresent = 1; |
| convert_ssid(pMac, &pProbeReq->ssId, &pr.SSID); |
| } |
| |
| if (!pr.SuppRates.present) { |
| pe_debug_rl("Mandatory IE Supported Rates not present!"); |
| return QDF_STATUS_E_FAILURE; |
| } else { |
| pProbeReq->suppRatesPresent = 1; |
| convert_supp_rates(pMac, &pProbeReq->supportedRates, |
| &pr.SuppRates); |
| } |
| |
| if (pr.ExtSuppRates.present) { |
| pProbeReq->extendedRatesPresent = 1; |
| convert_ext_supp_rates(pMac, &pProbeReq->extendedRates, |
| &pr.ExtSuppRates); |
| } |
| |
| if (pr.HTCaps.present) { |
| qdf_mem_copy(&pProbeReq->HTCaps, &pr.HTCaps, |
| sizeof(tDot11fIEHTCaps)); |
| } |
| |
| if (pr.WscProbeReq.present) { |
| pProbeReq->wscIePresent = 1; |
| memcpy(&pProbeReq->probeReqWscIeInfo, &pr.WscProbeReq, |
| sizeof(tDot11fIEWscProbeReq)); |
| } |
| if (pr.VHTCaps.present) { |
| qdf_mem_copy(&pProbeReq->VHTCaps, &pr.VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| } |
| if (pr.P2PProbeReq.present) { |
| pProbeReq->p2pIePresent = 1; |
| } |
| if (pr.he_cap.present) { |
| qdf_mem_copy(&pProbeReq->he_cap, &pr.he_cap, |
| sizeof(tDot11fIEhe_cap)); |
| pe_debug("11AX: HE cap IE present"); |
| } |
| return QDF_STATUS_SUCCESS; |
| } /* End sir_convert_probe_req_frame2_struct. */ |
| |
| |
| /** |
| * sir_validate_and_rectify_ies() - API to check malformed frame |
| * @mac_ctx: mac context |
| * @mgmt_frame: pointer to management frame |
| * @frame_bytes: no of bytes in frame |
| * @missing_rsn_bytes: missing rsn bytes |
| * |
| * The frame would contain fixed IEs of 12 bytes followed by variable IEs |
| * (Tagged elements). Every Tagged IE has tag number, tag length and data. |
| * Tag length indicates the size of data in bytes. |
| * This function checks for size of Frame received with the sum of all IEs. |
| * And also rectifies missing optional fields in IE. |
| * |
| * NOTE : Presently this function rectifies RSN capability in RSN IE, can |
| * be extended to rectify other optional fields in other IEs. |
| * |
| * Return: 0 on success, error number otherwise. |
| */ |
| QDF_STATUS |
| sir_validate_and_rectify_ies(tpAniSirGlobal mac_ctx, |
| uint8_t *mgmt_frame, |
| uint32_t frame_bytes, |
| uint32_t *missing_rsn_bytes) |
| { |
| uint32_t length = SIZE_OF_FIXED_PARAM; |
| uint8_t *ref_frame = NULL; |
| |
| /* Frame contains atleast one IE */ |
| if (frame_bytes > (SIZE_OF_FIXED_PARAM + |
| SIZE_OF_TAG_PARAM_NUM + SIZE_OF_TAG_PARAM_LEN)) { |
| while (length < frame_bytes) { |
| /* ref frame points to next IE */ |
| ref_frame = mgmt_frame + length; |
| length += (uint32_t)(SIZE_OF_TAG_PARAM_NUM + |
| SIZE_OF_TAG_PARAM_LEN + |
| (*(ref_frame + SIZE_OF_TAG_PARAM_NUM))); |
| } |
| if (length != frame_bytes) { |
| /* |
| * Workaround : Some APs may not include RSN |
| * Capability but the length of which is included in |
| * RSN IE length. This may cause in updating RSN |
| * Capability with junk value. To avoid this, add RSN |
| * Capability value with default value. |
| */ |
| if (ref_frame && (*ref_frame == RSNIEID) && |
| (length == (frame_bytes + |
| RSNIE_CAPABILITY_LEN))) { |
| /* Assume RSN Capability as 00 */ |
| qdf_mem_set((uint8_t *)(mgmt_frame + |
| (frame_bytes)), |
| RSNIE_CAPABILITY_LEN, |
| DEFAULT_RSNIE_CAP_VAL); |
| *missing_rsn_bytes = RSNIE_CAPABILITY_LEN; |
| pe_debug("Added RSN Capability to RSNIE as 0x00 0x00"); |
| return QDF_STATUS_SUCCESS; |
| } |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| void sir_copy_caps_info(tpAniSirGlobal mac_ctx, tDot11fFfCapabilities caps, |
| tpSirProbeRespBeacon pProbeResp) |
| { |
| pProbeResp->capabilityInfo.ess = caps.ess; |
| pProbeResp->capabilityInfo.ibss = caps.ibss; |
| pProbeResp->capabilityInfo.cfPollable = caps.cfPollable; |
| pProbeResp->capabilityInfo.cfPollReq = caps.cfPollReq; |
| pProbeResp->capabilityInfo.privacy = caps.privacy; |
| pProbeResp->capabilityInfo.shortPreamble = caps.shortPreamble; |
| pProbeResp->capabilityInfo.pbcc = caps.pbcc; |
| pProbeResp->capabilityInfo.channelAgility = caps.channelAgility; |
| pProbeResp->capabilityInfo.spectrumMgt = caps.spectrumMgt; |
| pProbeResp->capabilityInfo.qos = caps.qos; |
| pProbeResp->capabilityInfo.shortSlotTime = caps.shortSlotTime; |
| pProbeResp->capabilityInfo.apsd = caps.apsd; |
| pProbeResp->capabilityInfo.rrm = caps.rrm; |
| pProbeResp->capabilityInfo.dsssOfdm = caps.dsssOfdm; |
| pProbeResp->capabilityInfo.delayedBA = caps.delayedBA; |
| pProbeResp->capabilityInfo.immediateBA = caps.immediateBA; |
| } |
| |
| #ifdef WLAN_FEATURE_FILS_SK |
| static void populate_dot11f_fils_rsn(tpAniSirGlobal mac_ctx, |
| tDot11fIERSNOpaque *p_dot11f, |
| uint8_t *rsn_ie) |
| { |
| pe_debug("FILS RSN IE length %d", rsn_ie[1]); |
| if (rsn_ie[1]) { |
| p_dot11f->present = 1; |
| p_dot11f->num_data = rsn_ie[1]; |
| qdf_mem_copy(p_dot11f->data, &rsn_ie[2], rsn_ie[1]); |
| } |
| } |
| |
| void populate_dot11f_fils_params(tpAniSirGlobal mac_ctx, |
| tDot11fAssocRequest *frm, |
| tpPESession pe_session) |
| { |
| struct pe_fils_session *fils_info = pe_session->fils_info; |
| |
| /* Populate RSN IE with FILS AKM */ |
| populate_dot11f_fils_rsn(mac_ctx, &frm->RSNOpaque, |
| fils_info->rsn_ie); |
| |
| /* Populate FILS session IE */ |
| frm->fils_session.present = true; |
| qdf_mem_copy(frm->fils_session.session, |
| fils_info->fils_session, FILS_SESSION_LENGTH); |
| |
| /* Populate FILS Key confirmation IE */ |
| if (fils_info->key_auth_len) { |
| frm->fils_key_confirmation.present = true; |
| frm->fils_key_confirmation.num_key_auth = |
| fils_info->key_auth_len; |
| |
| qdf_mem_copy(frm->fils_key_confirmation.key_auth, |
| fils_info->key_auth, fils_info->key_auth_len); |
| } |
| } |
| |
| /** |
| * update_fils_data: update fils params from beacon/probe response |
| * @fils_ind: pointer to sir_fils_indication |
| * @fils_indication: pointer to tDot11fIEfils_indication |
| * |
| * Return: None |
| */ |
| void update_fils_data(struct sir_fils_indication *fils_ind, |
| tDot11fIEfils_indication *fils_indication) |
| { |
| uint8_t *data; |
| uint8_t remaining_data = fils_indication->num_variable_data; |
| |
| data = fils_indication->variable_data; |
| fils_ind->is_present = true; |
| fils_ind->is_ip_config_supported = |
| fils_indication->is_ip_config_supported; |
| fils_ind->is_fils_sk_auth_supported = |
| fils_indication->is_fils_sk_auth_supported; |
| fils_ind->is_fils_sk_auth_pfs_supported = |
| fils_indication->is_fils_sk_auth_pfs_supported; |
| fils_ind->is_pk_auth_supported = |
| fils_indication->is_pk_auth_supported; |
| if (fils_indication->is_cache_id_present) { |
| if (remaining_data < SIR_CACHE_IDENTIFIER_LEN) { |
| pe_err("Failed to copy Cache Identifier, Invalid remaining data %d", |
| remaining_data); |
| return; |
| } |
| fils_ind->cache_identifier.is_present = true; |
| qdf_mem_copy(fils_ind->cache_identifier.identifier, |
| data, SIR_CACHE_IDENTIFIER_LEN); |
| data = data + SIR_CACHE_IDENTIFIER_LEN; |
| remaining_data = remaining_data - SIR_CACHE_IDENTIFIER_LEN; |
| } |
| if (fils_indication->is_hessid_present) { |
| if (remaining_data < SIR_HESSID_LEN) { |
| pe_err("Failed to copy HESSID, Invalid remaining data %d", |
| remaining_data); |
| return; |
| } |
| fils_ind->hessid.is_present = true; |
| qdf_mem_copy(fils_ind->hessid.hessid, |
| data, SIR_HESSID_LEN); |
| data = data + SIR_HESSID_LEN; |
| remaining_data = remaining_data - SIR_HESSID_LEN; |
| } |
| if (fils_indication->realm_identifiers_cnt) { |
| if (remaining_data < (fils_indication->realm_identifiers_cnt * |
| SIR_REALM_LEN)) { |
| pe_err("Failed to copy Realm Identifier, Invalid remaining data %d realm_cnt %d", |
| remaining_data, |
| fils_indication->realm_identifiers_cnt); |
| return; |
| } |
| fils_ind->realm_identifier.is_present = true; |
| fils_ind->realm_identifier.realm_cnt = |
| fils_indication->realm_identifiers_cnt; |
| qdf_mem_copy(fils_ind->realm_identifier.realm, |
| data, fils_ind->realm_identifier.realm_cnt * |
| SIR_REALM_LEN); |
| } |
| } |
| #endif |
| |
| #ifdef WLAN_FEATURE_11AX_BSS_COLOR |
| static void update_bss_color_change_ie_from_probe_rsp( |
| tDot11fProbeResponse *prb_frm, |
| tpSirProbeRespBeacon prb_rsp_struct) |
| { |
| if (prb_frm->bss_color_change.present) { |
| pe_debug("11AX: HE BSS color change present"); |
| qdf_mem_copy(&prb_rsp_struct->vendor_he_bss_color_change, |
| &prb_frm->bss_color_change, |
| sizeof(tDot11fIEbss_color_change)); |
| } |
| } |
| #else |
| static inline void update_bss_color_change_ie_from_probe_rsp( |
| tDot11fProbeResponse *prb_frm, |
| tpSirProbeRespBeacon prb_rsp_struct) |
| {} |
| #endif |
| QDF_STATUS sir_convert_probe_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, |
| tpSirProbeRespBeacon pProbeResp) |
| { |
| uint32_t status; |
| tDot11fProbeResponse *pr; |
| |
| /* Ok, zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pProbeResp, sizeof(tSirProbeRespBeacon), 0); |
| |
| pr = qdf_mem_malloc(sizeof(tDot11fProbeResponse)); |
| if (NULL == pr) { |
| pe_err("Failed to allocate memory"); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_probe_response(pMac, pFrame, nFrame, pr, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse a Probe Response (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, |
| pFrame, nFrame); |
| qdf_mem_free(pr); |
| return QDF_STATUS_E_FAILURE; |
| } |
| /* & "transliterate" from a 'tDot11fProbeResponse' to a 'tSirProbeRespBeacon'... */ |
| |
| /* Timestamp */ |
| qdf_mem_copy((uint8_t *) pProbeResp->timeStamp, |
| (uint8_t *) &pr->TimeStamp, sizeof(tSirMacTimeStamp)); |
| |
| /* Beacon Interval */ |
| pProbeResp->beaconInterval = pr->BeaconInterval.interval; |
| |
| sir_copy_caps_info(pMac, pr->Capabilities, pProbeResp); |
| |
| if (!pr->SSID.present) { |
| pe_debug("Mandatory IE SSID not present!"); |
| } else { |
| pProbeResp->ssidPresent = 1; |
| convert_ssid(pMac, &pProbeResp->ssId, &pr->SSID); |
| } |
| |
| if (!pr->SuppRates.present) { |
| pe_debug_rl("Mandatory IE Supported Rates not present!"); |
| } else { |
| pProbeResp->suppRatesPresent = 1; |
| convert_supp_rates(pMac, &pProbeResp->supportedRates, |
| &pr->SuppRates); |
| } |
| |
| if (pr->ExtSuppRates.present) { |
| pProbeResp->extendedRatesPresent = 1; |
| convert_ext_supp_rates(pMac, &pProbeResp->extendedRates, |
| &pr->ExtSuppRates); |
| } |
| |
| if (pr->CFParams.present) { |
| pProbeResp->cfPresent = 1; |
| convert_cf_params(pMac, &pProbeResp->cfParamSet, &pr->CFParams); |
| } |
| |
| if (pr->Country.present) { |
| pProbeResp->countryInfoPresent = 1; |
| convert_country(pMac, &pProbeResp->countryInfoParam, |
| &pr->Country); |
| } |
| |
| if (pr->EDCAParamSet.present) { |
| pProbeResp->edcaPresent = 1; |
| convert_edca_param(pMac, &pProbeResp->edcaParams, |
| &pr->EDCAParamSet); |
| } |
| |
| if (pr->ChanSwitchAnn.present) { |
| pProbeResp->channelSwitchPresent = 1; |
| qdf_mem_copy(&pProbeResp->channelSwitchIE, &pr->ChanSwitchAnn, |
| sizeof(pProbeResp->channelSwitchIE)); |
| } |
| |
| if (pr->ext_chan_switch_ann.present) { |
| pProbeResp->ext_chan_switch_present = 1; |
| qdf_mem_copy(&pProbeResp->ext_chan_switch, |
| &pr->ext_chan_switch_ann, |
| sizeof(tDot11fIEext_chan_switch_ann)); |
| } |
| |
| if (pr->SuppOperatingClasses.present) { |
| pProbeResp->supp_operating_class_present = 1; |
| qdf_mem_copy(&pProbeResp->supp_operating_classes, |
| &pr->SuppOperatingClasses, |
| sizeof(tDot11fIESuppOperatingClasses)); |
| } |
| |
| if (pr->sec_chan_offset_ele.present) { |
| pProbeResp->sec_chan_offset_present = 1; |
| qdf_mem_copy(&pProbeResp->sec_chan_offset, |
| &pr->sec_chan_offset_ele, |
| sizeof(pProbeResp->sec_chan_offset)); |
| } |
| |
| if (pr->TPCReport.present) { |
| pProbeResp->tpcReportPresent = 1; |
| qdf_mem_copy(&pProbeResp->tpcReport, &pr->TPCReport, |
| sizeof(tDot11fIETPCReport)); |
| } |
| |
| if (pr->PowerConstraints.present) { |
| pProbeResp->powerConstraintPresent = 1; |
| qdf_mem_copy(&pProbeResp->localPowerConstraint, |
| &pr->PowerConstraints, |
| sizeof(tDot11fIEPowerConstraints)); |
| } |
| |
| if (pr->Quiet.present) { |
| pProbeResp->quietIEPresent = 1; |
| qdf_mem_copy(&pProbeResp->quietIE, &pr->Quiet, |
| sizeof(tDot11fIEQuiet)); |
| } |
| |
| if (pr->HTCaps.present) { |
| qdf_mem_copy(&pProbeResp->HTCaps, &pr->HTCaps, |
| sizeof(tDot11fIEHTCaps)); |
| } |
| |
| if (pr->HTInfo.present) { |
| qdf_mem_copy(&pProbeResp->HTInfo, &pr->HTInfo, |
| sizeof(tDot11fIEHTInfo)); |
| } |
| |
| if (pr->DSParams.present) { |
| pProbeResp->dsParamsPresent = 1; |
| pProbeResp->channelNumber = pr->DSParams.curr_channel; |
| } else if (pr->HTInfo.present) { |
| pProbeResp->channelNumber = pr->HTInfo.primaryChannel; |
| } |
| |
| if (pr->RSNOpaque.present) { |
| pProbeResp->rsnPresent = 1; |
| convert_rsn_opaque(pMac, &pProbeResp->rsn, &pr->RSNOpaque); |
| } |
| |
| if (pr->WPA.present) { |
| pProbeResp->wpaPresent = 1; |
| convert_wpa(pMac, &pProbeResp->wpa, &pr->WPA); |
| } |
| |
| if (pr->WMMParams.present) { |
| pProbeResp->wmeEdcaPresent = 1; |
| convert_wmm_params(pMac, &pProbeResp->edcaParams, &pr->WMMParams); |
| } |
| |
| if (pr->WMMInfoAp.present) { |
| pProbeResp->wmeInfoPresent = 1; |
| pe_debug("WMM Information Element present in Probe Response Frame!"); |
| } |
| |
| if (pr->WMMCaps.present) { |
| pProbeResp->wsmCapablePresent = 1; |
| } |
| |
| if (pr->ERPInfo.present) { |
| pProbeResp->erpPresent = 1; |
| convert_erp_info(pMac, &pProbeResp->erpIEInfo, &pr->ERPInfo); |
| } |
| if (pr->MobilityDomain.present) { |
| /* MobilityDomain */ |
| pProbeResp->mdiePresent = 1; |
| qdf_mem_copy((uint8_t *) &(pProbeResp->mdie[0]), |
| (uint8_t *) &(pr->MobilityDomain.MDID), |
| sizeof(uint16_t)); |
| pProbeResp->mdie[2] = |
| ((pr->MobilityDomain.overDSCap << 0) | (pr->MobilityDomain. |
| resourceReqCap << |
| 1)); |
| pe_debug("mdie=%02x%02x%02x", |
| (unsigned int)pProbeResp->mdie[0], |
| (unsigned int)pProbeResp->mdie[1], |
| (unsigned int)pProbeResp->mdie[2]); |
| } |
| |
| #if defined FEATURE_WLAN_ESE |
| if (pr->ESEVersion.present) |
| pProbeResp->is_ese_ver_ie_present = 1; |
| if (pr->QBSSLoad.present) { |
| qdf_mem_copy(&pProbeResp->QBSSLoad, &pr->QBSSLoad, |
| sizeof(tDot11fIEQBSSLoad)); |
| } |
| #endif |
| if (pr->P2PProbeRes.present) { |
| qdf_mem_copy(&pProbeResp->P2PProbeRes, &pr->P2PProbeRes, |
| sizeof(tDot11fIEP2PProbeRes)); |
| } |
| if (pr->VHTCaps.present) { |
| qdf_mem_copy(&pProbeResp->VHTCaps, &pr->VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| } |
| if (pr->VHTOperation.present) { |
| qdf_mem_copy(&pProbeResp->VHTOperation, &pr->VHTOperation, |
| sizeof(tDot11fIEVHTOperation)); |
| } |
| if (pr->VHTExtBssLoad.present) { |
| qdf_mem_copy(&pProbeResp->VHTExtBssLoad, &pr->VHTExtBssLoad, |
| sizeof(tDot11fIEVHTExtBssLoad)); |
| } |
| pProbeResp->Vendor1IEPresent = pr->Vendor1IE.present; |
| pProbeResp->Vendor3IEPresent = pr->Vendor3IE.present; |
| |
| pProbeResp->vendor_vht_ie.present = pr->vendor_vht_ie.present; |
| if (pr->vendor_vht_ie.present) |
| pProbeResp->vendor_vht_ie.sub_type = pr->vendor_vht_ie.sub_type; |
| if (pr->vendor_vht_ie.VHTCaps.present) { |
| qdf_mem_copy(&pProbeResp->vendor_vht_ie.VHTCaps, |
| &pr->vendor_vht_ie.VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| } |
| if (pr->vendor_vht_ie.VHTOperation.present) { |
| qdf_mem_copy(&pProbeResp->vendor_vht_ie.VHTOperation, |
| &pr->vendor_vht_ie.VHTOperation, |
| sizeof(tDot11fIEVHTOperation)); |
| } |
| /* Update HS 2.0 Information Element */ |
| if (pr->hs20vendor_ie.present) { |
| pe_debug("HS20 Indication Element Present, rel#:%u, id:%u", |
| pr->hs20vendor_ie.release_num, |
| pr->hs20vendor_ie.hs_id_present); |
| qdf_mem_copy(&pProbeResp->hs20vendor_ie, |
| &pr->hs20vendor_ie, |
| sizeof(tDot11fIEhs20vendor_ie) - |
| sizeof(pr->hs20vendor_ie.hs_id)); |
| if (pr->hs20vendor_ie.hs_id_present) |
| qdf_mem_copy(&pProbeResp->hs20vendor_ie.hs_id, |
| &pr->hs20vendor_ie.hs_id, |
| sizeof(pr->hs20vendor_ie.hs_id)); |
| } |
| if (pr->MBO_IE.present) { |
| pProbeResp->MBO_IE_present = true; |
| if (pr->MBO_IE.cellular_data_cap.present) |
| pProbeResp->MBO_capability = |
| pr->MBO_IE.cellular_data_cap.cellular_connectivity; |
| |
| if (pr->MBO_IE.assoc_disallowed.present) { |
| pProbeResp->assoc_disallowed = true; |
| pProbeResp->assoc_disallowed_reason = |
| pr->MBO_IE.assoc_disallowed.reason_code; |
| } |
| } |
| |
| if (pr->QCN_IE.present) { |
| pProbeResp->QCN_IE.is_present = true; |
| |
| if (pr->QCN_IE.version[0] == QCN_IE_VERSION_SUBATTR_ID) { |
| pProbeResp->QCN_IE.version |
| = pr->QCN_IE.version[2]; |
| pProbeResp->QCN_IE.sub_version |
| = pr->QCN_IE.version[3]; |
| } |
| } |
| |
| if (pr->he_cap.present) { |
| pe_debug("11AX: HE cap IE present"); |
| qdf_mem_copy(&pProbeResp->he_cap, &pr->he_cap, |
| sizeof(tDot11fIEhe_cap)); |
| } |
| if (pr->he_op.present) { |
| pe_debug("11AX: HE operation IE present"); |
| qdf_mem_copy(&pProbeResp->he_op, &pr->he_op, |
| sizeof(tDot11fIEhe_op)); |
| } |
| |
| update_bss_color_change_ie_from_probe_rsp(pr, pProbeResp); |
| |
| qdf_mem_free(pr); |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_probe_frame2_struct. */ |
| |
| QDF_STATUS |
| sir_convert_assoc_req_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, tpSirAssocReq pAssocReq) |
| { |
| tDot11fAssocRequest *ar; |
| uint32_t status; |
| |
| ar = qdf_mem_malloc(sizeof(tDot11fAssocRequest)); |
| if (NULL == ar) { |
| pe_err("Failed to allocate memory"); |
| return QDF_STATUS_E_NOMEM; |
| } |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pAssocReq, sizeof(tSirAssocReq), 0); |
| |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_assoc_request(pMac, pFrame, nFrame, ar, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse an Association Request (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| qdf_mem_free(ar); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking an Assoication Request (0x%08x, %d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fAssocRequest' to a 'tSirAssocReq'... */ |
| |
| /* make sure this is seen as an assoc request */ |
| pAssocReq->reassocRequest = 0; |
| |
| /* Capabilities */ |
| pAssocReq->capabilityInfo.ess = ar->Capabilities.ess; |
| pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss; |
| pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable; |
| pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq; |
| pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy; |
| pAssocReq->capabilityInfo.shortPreamble = |
| ar->Capabilities.shortPreamble; |
| pAssocReq->capabilityInfo.pbcc = ar->Capabilities.pbcc; |
| pAssocReq->capabilityInfo.channelAgility = |
| ar->Capabilities.channelAgility; |
| pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt; |
| pAssocReq->capabilityInfo.qos = ar->Capabilities.qos; |
| pAssocReq->capabilityInfo.shortSlotTime = |
| ar->Capabilities.shortSlotTime; |
| pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd; |
| pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm; |
| pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm; |
| pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA; |
| pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA; |
| |
| /* Listen Interval */ |
| pAssocReq->listenInterval = ar->ListenInterval.interval; |
| |
| /* SSID */ |
| if (ar->SSID.present) { |
| pAssocReq->ssidPresent = 1; |
| convert_ssid(pMac, &pAssocReq->ssId, &ar->SSID); |
| } |
| /* Supported Rates */ |
| if (ar->SuppRates.present) { |
| pAssocReq->suppRatesPresent = 1; |
| convert_supp_rates(pMac, &pAssocReq->supportedRates, |
| &ar->SuppRates); |
| } |
| /* Extended Supported Rates */ |
| if (ar->ExtSuppRates.present) { |
| pAssocReq->extendedRatesPresent = 1; |
| convert_ext_supp_rates(pMac, &pAssocReq->extendedRates, |
| &ar->ExtSuppRates); |
| } |
| /* QOS Capabilities: */ |
| if (ar->QOSCapsStation.present) { |
| pAssocReq->qosCapabilityPresent = 1; |
| convert_qos_caps_station(pMac, &pAssocReq->qosCapability, |
| &ar->QOSCapsStation); |
| } |
| /* WPA */ |
| if (ar->WPAOpaque.present) { |
| pAssocReq->wpaPresent = 1; |
| convert_wpa_opaque(pMac, &pAssocReq->wpa, &ar->WPAOpaque); |
| } |
| #ifdef FEATURE_WLAN_WAPI |
| if (ar->WAPIOpaque.present) { |
| pAssocReq->wapiPresent = 1; |
| convert_wapi_opaque(pMac, &pAssocReq->wapi, &ar->WAPIOpaque); |
| } |
| #endif |
| /* RSN */ |
| if (ar->RSNOpaque.present) { |
| pAssocReq->rsnPresent = 1; |
| convert_rsn_opaque(pMac, &pAssocReq->rsn, &ar->RSNOpaque); |
| } |
| /* WSC IE */ |
| if (ar->WscIEOpaque.present) { |
| pAssocReq->addIEPresent = 1; |
| convert_wsc_opaque(pMac, &pAssocReq->addIE, &ar->WscIEOpaque); |
| } |
| |
| if (ar->P2PIEOpaque.present) { |
| pAssocReq->addIEPresent = 1; |
| convert_p2p_opaque(pMac, &pAssocReq->addIE, &ar->P2PIEOpaque); |
| } |
| #ifdef WLAN_FEATURE_WFD |
| if (ar->WFDIEOpaque.present) { |
| pAssocReq->addIEPresent = 1; |
| convert_wfd_opaque(pMac, &pAssocReq->addIE, &ar->WFDIEOpaque); |
| } |
| #endif |
| |
| /* Power Capabilities */ |
| if (ar->PowerCaps.present) { |
| pAssocReq->powerCapabilityPresent = 1; |
| convert_power_caps(pMac, &pAssocReq->powerCapability, |
| &ar->PowerCaps); |
| } |
| /* Supported Channels */ |
| if (ar->SuppChannels.present) { |
| pAssocReq->supportedChannelsPresent = 1; |
| convert_supp_channels(pMac, &pAssocReq->supportedChannels, |
| &ar->SuppChannels); |
| } |
| |
| if (ar->HTCaps.present) { |
| qdf_mem_copy(&pAssocReq->HTCaps, &ar->HTCaps, |
| sizeof(tDot11fIEHTCaps)); |
| } |
| |
| if (ar->WMMInfoStation.present) { |
| pAssocReq->wmeInfoPresent = 1; |
| qdf_mem_copy(&pAssocReq->WMMInfoStation, &ar->WMMInfoStation, |
| sizeof(tDot11fIEWMMInfoStation)); |
| |
| } |
| |
| if (ar->WMMCaps.present) |
| pAssocReq->wsmCapablePresent = 1; |
| |
| if (!pAssocReq->ssidPresent) { |
| pe_debug("Received Assoc without SSID IE"); |
| qdf_mem_free(ar); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent) { |
| pe_debug("Received Assoc without supp rate IE"); |
| qdf_mem_free(ar); |
| return QDF_STATUS_E_FAILURE; |
| } |
| if (ar->VHTCaps.present) { |
| qdf_mem_copy(&pAssocReq->VHTCaps, &ar->VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| pe_debug("Received Assoc Req with VHT Cap"); |
| lim_log_vht_cap(pMac, &pAssocReq->VHTCaps); |
| } |
| if (ar->OperatingMode.present) { |
| qdf_mem_copy(&pAssocReq->operMode, &ar->OperatingMode, |
| sizeof(tDot11fIEOperatingMode)); |
| pe_debug("Received Assoc Req with Operating Mode IE"); |
| lim_log_operating_mode(pMac, &pAssocReq->operMode); |
| } |
| if (ar->ExtCap.present) { |
| struct s_ext_cap *ext_cap; |
| |
| qdf_mem_copy(&pAssocReq->ExtCap, &ar->ExtCap, |
| sizeof(tDot11fIEExtCap)); |
| ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes; |
| pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d", |
| ext_cap->timing_meas, ext_cap->fine_time_meas_initiator, |
| ext_cap->fine_time_meas_responder); |
| } |
| |
| pAssocReq->vendor_vht_ie.present = ar->vendor_vht_ie.present; |
| if (ar->vendor_vht_ie.present) { |
| pAssocReq->vendor_vht_ie.sub_type = ar->vendor_vht_ie.sub_type; |
| if (ar->vendor_vht_ie.VHTCaps.present) { |
| qdf_mem_copy(&pAssocReq->vendor_vht_ie.VHTCaps, |
| &ar->vendor_vht_ie.VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| pe_debug("Received Assoc Request with Vendor specific VHT Cap"); |
| lim_log_vht_cap(pMac, &pAssocReq->VHTCaps); |
| } |
| } |
| if (ar->he_cap.present) { |
| qdf_mem_copy(&pAssocReq->he_cap, &ar->he_cap, |
| sizeof(tDot11fIEhe_cap)); |
| pe_debug("Received Assoc Req with HE Capability IE"); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, |
| &pAssocReq->he_cap, sizeof(tDot11fIEhe_cap)); |
| } |
| qdf_mem_free(ar); |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_assoc_req_frame2_struct. */ |
| |
| /** |
| * dot11f_parse_assoc_response() - API to parse Assoc IE buffer to struct |
| * @mac_ctx: MAC context |
| * @p_buf: Pointer to the assoc IE buffer |
| * @n_buf: length of the @p_buf |
| * @p_frm: Struct to populate the IE buffer after parsing |
| * @append_ie: Boolean to indicate whether to reset @p_frm or not. If @append_ie |
| * is true, @p_frm struct is not reset to zeros. |
| * |
| * Return: QDF_STATUS |
| */ |
| static QDF_STATUS dot11f_parse_assoc_response(tpAniSirGlobal mac_ctx, |
| uint8_t *p_buf, uint32_t n_buf, |
| tDot11fAssocResponse *p_frm, |
| bool append_ie) |
| { |
| uint32_t status; |
| |
| status = dot11f_unpack_assoc_response(mac_ctx, p_buf, |
| n_buf, p_frm, append_ie); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse an Association Response (0x%08x, %d bytes):", |
| status, n_buf); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| p_buf, n_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| #ifdef WLAN_FEATURE_FILS_SK |
| /** |
| * fils_convert_assoc_rsp_frame2_struct() - Copy FILS IE's to Assoc rsp struct |
| * @ar: frame parser Assoc response struct |
| * @pAssocRsp: LIM Assoc response |
| * |
| * Return: None |
| */ |
| static void fils_convert_assoc_rsp_frame2_struct(tDot11fAssocResponse *ar, |
| tpSirAssocRsp pAssocRsp) |
| { |
| if (ar->fils_session.present) { |
| pe_debug("fils session IE present"); |
| pAssocRsp->fils_session.present = true; |
| qdf_mem_copy(pAssocRsp->fils_session.session, |
| ar->fils_session.session, |
| DOT11F_IE_FILS_SESSION_MAX_LEN); |
| } |
| |
| if (ar->fils_key_confirmation.present) { |
| pe_debug("fils key conf IE present"); |
| pAssocRsp->fils_key_auth.num_key_auth = |
| ar->fils_key_confirmation.num_key_auth; |
| qdf_mem_copy(pAssocRsp->fils_key_auth.key_auth, |
| ar->fils_key_confirmation.key_auth, |
| pAssocRsp->fils_key_auth.num_key_auth); |
| } |
| |
| if (ar->fils_kde.present) { |
| pe_debug("fils kde IE present %d", |
| ar->fils_kde.num_kde_list); |
| pAssocRsp->fils_kde.num_kde_list = |
| ar->fils_kde.num_kde_list; |
| qdf_mem_copy(pAssocRsp->fils_kde.key_rsc, |
| ar->fils_kde.key_rsc, KEY_RSC_LEN); |
| qdf_mem_copy(&pAssocRsp->fils_kde.kde_list, |
| &ar->fils_kde.kde_list, |
| pAssocRsp->fils_kde.num_kde_list); |
| } |
| |
| if (ar->fils_hlp_container.present) { |
| pe_debug("FILS HLP container IE present"); |
| sir_copy_mac_addr(pAssocRsp->dst_mac.bytes, |
| ar->fils_hlp_container.dest_mac); |
| sir_copy_mac_addr(pAssocRsp->src_mac.bytes, |
| ar->fils_hlp_container.src_mac); |
| pAssocRsp->hlp_data_len = ar->fils_hlp_container.num_hlp_packet; |
| qdf_mem_copy(pAssocRsp->hlp_data, |
| ar->fils_hlp_container.hlp_packet, |
| pAssocRsp->hlp_data_len); |
| |
| if (ar->fragment_ie.present) { |
| pe_debug("FILS fragment ie present"); |
| qdf_mem_copy(pAssocRsp->hlp_data + |
| pAssocRsp->hlp_data_len, |
| ar->fragment_ie.data, |
| ar->fragment_ie.num_data); |
| pAssocRsp->hlp_data_len += ar->fragment_ie.num_data; |
| } |
| } |
| } |
| #else |
| static inline void fils_convert_assoc_rsp_frame2_struct(tDot11fAssocResponse |
| *ar, tpSirAssocRsp |
| pAssocRsp) |
| { } |
| #endif |
| |
| QDF_STATUS |
| sir_convert_assoc_resp_frame2_struct(tpAniSirGlobal pMac, |
| tpPESession session_entry, |
| uint8_t *pFrame, uint32_t nFrame, |
| tpSirAssocRsp pAssocRsp) |
| { |
| tDot11fAssocResponse *ar; |
| uint32_t status; |
| uint8_t cnt = 0; |
| |
| ar = qdf_mem_malloc(sizeof(*ar)); |
| if (!ar) { |
| pe_err("Assoc rsp mem alloc fails"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| /* decrypt the cipher text using AEAD decryption */ |
| if (lim_is_fils_connection(session_entry)) { |
| status = aead_decrypt_assoc_rsp(pMac, session_entry, |
| ar, pFrame, &nFrame); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| pe_err("FILS assoc rsp AEAD decrypt fails"); |
| qdf_mem_free(ar); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| |
| status = dot11f_parse_assoc_response(pMac, pFrame, nFrame, ar, false); |
| if (QDF_STATUS_SUCCESS != status) { |
| qdf_mem_free(ar); |
| return status; |
| } |
| |
| |
| /* Capabilities */ |
| pAssocRsp->capabilityInfo.ess = ar->Capabilities.ess; |
| pAssocRsp->capabilityInfo.ibss = ar->Capabilities.ibss; |
| pAssocRsp->capabilityInfo.cfPollable = ar->Capabilities.cfPollable; |
| pAssocRsp->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq; |
| pAssocRsp->capabilityInfo.privacy = ar->Capabilities.privacy; |
| pAssocRsp->capabilityInfo.shortPreamble = |
| ar->Capabilities.shortPreamble; |
| pAssocRsp->capabilityInfo.pbcc = ar->Capabilities.pbcc; |
| pAssocRsp->capabilityInfo.channelAgility = |
| ar->Capabilities.channelAgility; |
| pAssocRsp->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt; |
| pAssocRsp->capabilityInfo.qos = ar->Capabilities.qos; |
| pAssocRsp->capabilityInfo.shortSlotTime = |
| ar->Capabilities.shortSlotTime; |
| pAssocRsp->capabilityInfo.apsd = ar->Capabilities.apsd; |
| pAssocRsp->capabilityInfo.rrm = ar->Capabilities.rrm; |
| pAssocRsp->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm; |
| pAssocRsp->capabilityInfo.delayedBA = ar->Capabilities.delayedBA; |
| pAssocRsp->capabilityInfo.immediateBA = ar->Capabilities.immediateBA; |
| |
| pAssocRsp->statusCode = ar->Status.status; |
| pAssocRsp->aid = ar->AID.associd; |
| #ifdef WLAN_FEATURE_11W |
| if (ar->TimeoutInterval.present) { |
| pAssocRsp->TimeoutInterval.present = 1; |
| pAssocRsp->TimeoutInterval.timeoutType = |
| ar->TimeoutInterval.timeoutType; |
| pAssocRsp->TimeoutInterval.timeoutValue = |
| ar->TimeoutInterval.timeoutValue; |
| } |
| #endif |
| |
| if (!ar->SuppRates.present) { |
| pAssocRsp->suppRatesPresent = 0; |
| pe_debug_rl("Mandatory IE Supported Rates not present!"); |
| } else { |
| pAssocRsp->suppRatesPresent = 1; |
| convert_supp_rates(pMac, &pAssocRsp->supportedRates, |
| &ar->SuppRates); |
| } |
| |
| if (ar->ExtSuppRates.present) { |
| pAssocRsp->extendedRatesPresent = 1; |
| convert_ext_supp_rates(pMac, &pAssocRsp->extendedRates, |
| &ar->ExtSuppRates); |
| } |
| |
| if (ar->EDCAParamSet.present) { |
| pAssocRsp->edcaPresent = 1; |
| convert_edca_param(pMac, &pAssocRsp->edca, &ar->EDCAParamSet); |
| } |
| if (ar->WMMParams.present) { |
| pAssocRsp->wmeEdcaPresent = 1; |
| convert_wmm_params(pMac, &pAssocRsp->edca, &ar->WMMParams); |
| pe_debug("Received Assoc Resp with WMM Param"); |
| __print_wmm_params(pMac, &ar->WMMParams); |
| } |
| |
| if (ar->HTCaps.present) { |
| pe_debug("Received Assoc Resp with HT Cap"); |
| qdf_mem_copy(&pAssocRsp->HTCaps, &ar->HTCaps, |
| sizeof(tDot11fIEHTCaps)); |
| } |
| |
| if (ar->HTInfo.present) { |
| pe_debug("Received Assoc Resp with HT Info"); |
| qdf_mem_copy(&pAssocRsp->HTInfo, &ar->HTInfo, |
| sizeof(tDot11fIEHTInfo)); |
| } |
| if (ar->MobilityDomain.present) { |
| /* MobilityDomain */ |
| pAssocRsp->mdiePresent = 1; |
| qdf_mem_copy((uint8_t *) &(pAssocRsp->mdie[0]), |
| (uint8_t *) &(ar->MobilityDomain.MDID), |
| sizeof(uint16_t)); |
| pAssocRsp->mdie[2] = ((ar->MobilityDomain.overDSCap << 0) | |
| (ar->MobilityDomain.resourceReqCap << 1)); |
| pe_debug("new mdie=%02x%02x%02x", |
| (unsigned int)pAssocRsp->mdie[0], |
| (unsigned int)pAssocRsp->mdie[1], |
| (unsigned int)pAssocRsp->mdie[2]); |
| } |
| |
| if (ar->FTInfo.present) { |
| pe_debug("FT Info present %d %d %d", |
| ar->FTInfo.R0KH_ID.num_PMK_R0_ID, |
| ar->FTInfo.R0KH_ID.present, ar->FTInfo.R1KH_ID.present); |
| pAssocRsp->ftinfoPresent = 1; |
| qdf_mem_copy(&pAssocRsp->FTInfo, &ar->FTInfo, |
| sizeof(tDot11fIEFTInfo)); |
| } |
| |
| if (ar->num_RICDataDesc && ar->num_RICDataDesc <= 2) { |
| for (cnt = 0; cnt < ar->num_RICDataDesc; cnt++) { |
| if (ar->RICDataDesc[cnt].present) { |
| qdf_mem_copy(&pAssocRsp->RICData[cnt], |
| &ar->RICDataDesc[cnt], |
| sizeof(tDot11fIERICDataDesc)); |
| } |
| } |
| pAssocRsp->num_RICData = ar->num_RICDataDesc; |
| pAssocRsp->ricPresent = true; |
| } |
| |
| #ifdef FEATURE_WLAN_ESE |
| if (ar->num_WMMTSPEC) { |
| pAssocRsp->num_tspecs = ar->num_WMMTSPEC; |
| for (cnt = 0; cnt < ar->num_WMMTSPEC; cnt++) { |
| qdf_mem_copy(&pAssocRsp->TSPECInfo[cnt], |
| &ar->WMMTSPEC[cnt], |
| sizeof(tDot11fIEWMMTSPEC)); |
| } |
| pAssocRsp->tspecPresent = true; |
| } |
| |
| if (ar->ESETrafStrmMet.present) { |
| pAssocRsp->tsmPresent = 1; |
| qdf_mem_copy(&pAssocRsp->tsmIE.tsid, |
| &ar->ESETrafStrmMet.tsid, |
| sizeof(tSirMacESETSMIE)); |
| } |
| #endif |
| |
| if (ar->VHTCaps.present) { |
| qdf_mem_copy(&pAssocRsp->VHTCaps, &ar->VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| pe_debug("Received Assoc Response with VHT Cap"); |
| lim_log_vht_cap(pMac, &pAssocRsp->VHTCaps); |
| } |
| if (ar->VHTOperation.present) { |
| qdf_mem_copy(&pAssocRsp->VHTOperation, &ar->VHTOperation, |
| sizeof(tDot11fIEVHTOperation)); |
| pe_debug("Received Assoc Response with VHT Operation"); |
| lim_log_vht_operation(pMac, &pAssocRsp->VHTOperation); |
| } |
| |
| if (ar->ExtCap.present) { |
| struct s_ext_cap *ext_cap; |
| |
| qdf_mem_copy(&pAssocRsp->ExtCap, &ar->ExtCap, |
| sizeof(tDot11fIEExtCap)); |
| ext_cap = (struct s_ext_cap *)&pAssocRsp->ExtCap.bytes; |
| pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d", |
| ext_cap->timing_meas, ext_cap->fine_time_meas_initiator, |
| ext_cap->fine_time_meas_responder); |
| } |
| |
| if (ar->QosMapSet.present) { |
| pAssocRsp->QosMapSet.present = 1; |
| convert_qos_mapset_frame(pMac, &pAssocRsp->QosMapSet, |
| &ar->QosMapSet); |
| pe_debug("Received Assoc Response with Qos Map Set"); |
| lim_log_qos_map_set(pMac, &pAssocRsp->QosMapSet); |
| } |
| |
| pAssocRsp->vendor_vht_ie.present = ar->vendor_vht_ie.present; |
| if (ar->vendor_vht_ie.present) |
| pAssocRsp->vendor_vht_ie.sub_type = ar->vendor_vht_ie.sub_type; |
| if (ar->OBSSScanParameters.present) { |
| qdf_mem_copy(&pAssocRsp->obss_scanparams, |
| &ar->OBSSScanParameters, |
| sizeof(struct sDot11fIEOBSSScanParameters)); |
| } |
| if (ar->vendor_vht_ie.VHTCaps.present) { |
| qdf_mem_copy(&pAssocRsp->vendor_vht_ie.VHTCaps, |
| &ar->vendor_vht_ie.VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| pe_debug("Received Assoc Response with Vendor specific VHT Cap"); |
| lim_log_vht_cap(pMac, &pAssocRsp->VHTCaps); |
| } |
| if (ar->vendor_vht_ie.VHTOperation.present) { |
| qdf_mem_copy(&pAssocRsp->vendor_vht_ie.VHTOperation, |
| &ar->vendor_vht_ie.VHTOperation, |
| sizeof(tDot11fIEVHTOperation)); |
| pe_debug("Received Assoc Response with Vendor specific VHT Oper"); |
| lim_log_vht_operation(pMac, &pAssocRsp->VHTOperation); |
| } |
| |
| if (ar->he_cap.present) { |
| pe_debug("11AX: HE cap IE present"); |
| qdf_mem_copy(&pAssocRsp->he_cap, &ar->he_cap, |
| sizeof(tDot11fIEhe_cap)); |
| } |
| if (ar->he_op.present) { |
| pe_debug("11AX: HE Operation IE present"); |
| qdf_mem_copy(&pAssocRsp->he_op, &ar->he_op, |
| sizeof(tDot11fIEhe_op)); |
| pe_debug("bss_clr %d def_pe %d part_bss_clr %d bss_col_dis %d", |
| pAssocRsp->he_op.bss_color, |
| pAssocRsp->he_op.default_pe, |
| pAssocRsp->he_op.partial_bss_col, |
| pAssocRsp->he_op.bss_col_disabled); |
| } |
| |
| if (ar->mu_edca_param_set.present) { |
| pe_debug("11AX: HE MU EDCA param IE present"); |
| pAssocRsp->mu_edca_present = true; |
| convert_mu_edca_param(pMac, &pAssocRsp->mu_edca, |
| &ar->mu_edca_param_set); |
| } |
| |
| if (ar->MBO_IE.present && ar->MBO_IE.rssi_assoc_rej.present) { |
| qdf_mem_copy(&pAssocRsp->rssi_assoc_rej, |
| &ar->MBO_IE.rssi_assoc_rej, |
| sizeof(tDot11fTLVrssi_assoc_rej)); |
| pe_debug("Received Assoc Response with rssi based assoc rej"); |
| } |
| |
| fils_convert_assoc_rsp_frame2_struct(ar, pAssocRsp); |
| |
| qdf_mem_free(ar); |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_assoc_resp_frame2_struct. */ |
| |
| QDF_STATUS |
| sir_convert_reassoc_req_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, tpSirAssocReq pAssocReq) |
| { |
| tDot11fReAssocRequest *ar; |
| uint32_t status; |
| |
| ar = qdf_mem_malloc(sizeof(*ar)); |
| if (!ar) { |
| pe_err("mem alloc failed"); |
| return QDF_STATUS_E_NOMEM; |
| } |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pAssocReq, sizeof(tSirAssocReq), 0); |
| |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_re_assoc_request(pMac, pFrame, nFrame, |
| ar, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse a Re-association Request (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking a Re-association Request (0x%08x, %d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fReAssocRequest' to a 'tSirAssocReq'... */ |
| |
| /* make sure this is seen as a re-assoc request */ |
| pAssocReq->reassocRequest = 1; |
| |
| /* Capabilities */ |
| pAssocReq->capabilityInfo.ess = ar->Capabilities.ess; |
| pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss; |
| pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable; |
| pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq; |
| pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy; |
| pAssocReq->capabilityInfo.shortPreamble = ar->Capabilities.shortPreamble; |
| pAssocReq->capabilityInfo.pbcc = ar->Capabilities.pbcc; |
| pAssocReq->capabilityInfo.channelAgility = |
| ar->Capabilities.channelAgility; |
| pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt; |
| pAssocReq->capabilityInfo.qos = ar->Capabilities.qos; |
| pAssocReq->capabilityInfo.shortSlotTime = ar->Capabilities.shortSlotTime; |
| pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd; |
| pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm; |
| pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm; |
| pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA; |
| pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA; |
| |
| /* Listen Interval */ |
| pAssocReq->listenInterval = ar->ListenInterval.interval; |
| |
| /* SSID */ |
| if (ar->SSID.present) { |
| pAssocReq->ssidPresent = 1; |
| convert_ssid(pMac, &pAssocReq->ssId, &ar->SSID); |
| } |
| /* Supported Rates */ |
| if (ar->SuppRates.present) { |
| pAssocReq->suppRatesPresent = 1; |
| convert_supp_rates(pMac, &pAssocReq->supportedRates, |
| &ar->SuppRates); |
| } |
| /* Extended Supported Rates */ |
| if (ar->ExtSuppRates.present) { |
| pAssocReq->extendedRatesPresent = 1; |
| convert_ext_supp_rates(pMac, &pAssocReq->extendedRates, |
| &ar->ExtSuppRates); |
| } |
| /* QOS Capabilities: */ |
| if (ar->QOSCapsStation.present) { |
| pAssocReq->qosCapabilityPresent = 1; |
| convert_qos_caps_station(pMac, &pAssocReq->qosCapability, |
| &ar->QOSCapsStation); |
| } |
| /* WPA */ |
| if (ar->WPAOpaque.present) { |
| pAssocReq->wpaPresent = 1; |
| convert_wpa_opaque(pMac, &pAssocReq->wpa, &ar->WPAOpaque); |
| } |
| /* RSN */ |
| if (ar->RSNOpaque.present) { |
| pAssocReq->rsnPresent = 1; |
| convert_rsn_opaque(pMac, &pAssocReq->rsn, &ar->RSNOpaque); |
| } |
| |
| /* Power Capabilities */ |
| if (ar->PowerCaps.present) { |
| pAssocReq->powerCapabilityPresent = 1; |
| convert_power_caps(pMac, &pAssocReq->powerCapability, |
| &ar->PowerCaps); |
| } |
| /* Supported Channels */ |
| if (ar->SuppChannels.present) { |
| pAssocReq->supportedChannelsPresent = 1; |
| convert_supp_channels(pMac, &pAssocReq->supportedChannels, |
| &ar->SuppChannels); |
| } |
| |
| if (ar->HTCaps.present) { |
| qdf_mem_copy(&pAssocReq->HTCaps, &ar->HTCaps, |
| sizeof(tDot11fIEHTCaps)); |
| } |
| |
| if (ar->WMMInfoStation.present) { |
| pAssocReq->wmeInfoPresent = 1; |
| qdf_mem_copy(&pAssocReq->WMMInfoStation, &ar->WMMInfoStation, |
| sizeof(tDot11fIEWMMInfoStation)); |
| |
| } |
| |
| if (ar->WMMCaps.present) |
| pAssocReq->wsmCapablePresent = 1; |
| |
| if (!pAssocReq->ssidPresent) { |
| pe_debug("Received Assoc without SSID IE"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent) { |
| pe_debug("Received Assoc without supp rate IE"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| /* Why no call to 'updateAssocReqFromPropCapability' here, like */ |
| /* there is in 'sir_convert_assoc_req_frame2_struct'? */ |
| |
| /* WSC IE */ |
| if (ar->WscIEOpaque.present) { |
| pAssocReq->addIEPresent = 1; |
| convert_wsc_opaque(pMac, &pAssocReq->addIE, &ar->WscIEOpaque); |
| } |
| |
| if (ar->P2PIEOpaque.present) { |
| pAssocReq->addIEPresent = 1; |
| convert_p2p_opaque(pMac, &pAssocReq->addIE, &ar->P2PIEOpaque); |
| } |
| #ifdef WLAN_FEATURE_WFD |
| if (ar->WFDIEOpaque.present) { |
| pAssocReq->addIEPresent = 1; |
| convert_wfd_opaque(pMac, &pAssocReq->addIE, &ar->WFDIEOpaque); |
| } |
| #endif |
| |
| if (ar->VHTCaps.present) { |
| qdf_mem_copy(&pAssocReq->VHTCaps, &ar->VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| } |
| if (ar->OperatingMode.present) { |
| qdf_mem_copy(&pAssocReq->operMode, &ar->OperatingMode, |
| sizeof(tDot11fIEOperatingMode)); |
| pe_warn("Received Assoc Req with Operating Mode IE"); |
| lim_log_operating_mode(pMac, &pAssocReq->operMode); |
| } |
| if (ar->ExtCap.present) { |
| struct s_ext_cap *ext_cap; |
| |
| qdf_mem_copy(&pAssocReq->ExtCap, &ar->ExtCap, |
| sizeof(tDot11fIEExtCap)); |
| ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes; |
| pe_debug("timingMeas: %d, finetimingMeas Init: %d, Resp: %d", |
| ext_cap->timing_meas, ext_cap->fine_time_meas_initiator, |
| ext_cap->fine_time_meas_responder); |
| } |
| if (ar->he_cap.present) { |
| qdf_mem_copy(&pAssocReq->he_cap, &ar->he_cap, |
| sizeof(tDot11fIEhe_cap)); |
| } |
| qdf_mem_free(ar); |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_reassoc_req_frame2_struct. */ |
| |
| #ifdef FEATURE_WLAN_ESE |
| QDF_STATUS |
| sir_beacon_ie_ese_bcn_report(tpAniSirGlobal pMac, |
| uint8_t *pPayload, const uint32_t nPayload, |
| uint8_t **outIeBuf, uint32_t *pOutIeLen) |
| { |
| tDot11fBeaconIEs *pBies = NULL; |
| uint32_t status = QDF_STATUS_SUCCESS; |
| QDF_STATUS retStatus = QDF_STATUS_SUCCESS; |
| tSirEseBcnReportMandatoryIe eseBcnReportMandatoryIe; |
| |
| /* To store how many bytes are required to be allocated |
| for Bcn report mandatory Ies */ |
| uint16_t numBytes = 0, freeBytes = 0; |
| uint8_t *pos = NULL; |
| |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) &eseBcnReportMandatoryIe, |
| sizeof(eseBcnReportMandatoryIe), 0); |
| pBies = qdf_mem_malloc(sizeof(tDot11fBeaconIEs)); |
| if (NULL == pBies) { |
| pe_err("Failed to allocate memory"); |
| return QDF_STATUS_E_NOMEM; |
| } |
| qdf_mem_zero(pBies, sizeof(tDot11fBeaconIEs)); |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_beacon_i_es(pMac, pPayload, nPayload, |
| pBies, false); |
| |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):", |
| status, nPayload); |
| qdf_mem_free(pBies); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):", |
| status, nPayload); |
| } |
| /* & "transliterate" from a 'tDot11fBeaconIEs' to a 'eseBcnReportMandatoryIe'... */ |
| if (!pBies->SSID.present) { |
| pe_debug("Mandatory IE SSID not present!"); |
| } else { |
| eseBcnReportMandatoryIe.ssidPresent = 1; |
| convert_ssid(pMac, &eseBcnReportMandatoryIe.ssId, &pBies->SSID); |
| /* 1 for EID, 1 for length and length bytes */ |
| numBytes += 1 + 1 + eseBcnReportMandatoryIe.ssId.length; |
| } |
| |
| if (!pBies->SuppRates.present) { |
| pe_debug_rl("Mandatory IE Supported Rates not present!"); |
| } else { |
| eseBcnReportMandatoryIe.suppRatesPresent = 1; |
| convert_supp_rates(pMac, &eseBcnReportMandatoryIe.supportedRates, |
| &pBies->SuppRates); |
| numBytes += |
| 1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates; |
| } |
| |
| if (pBies->FHParamSet.present) { |
| eseBcnReportMandatoryIe.fhParamPresent = 1; |
| convert_fh_params(pMac, &eseBcnReportMandatoryIe.fhParamSet, |
| &pBies->FHParamSet); |
| numBytes += 1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX; |
| } |
| |
| if (pBies->DSParams.present) { |
| eseBcnReportMandatoryIe.dsParamsPresent = 1; |
| eseBcnReportMandatoryIe.dsParamSet.channelNumber = |
| pBies->DSParams.curr_channel; |
| numBytes += 1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX; |
| } |
| |
| if (pBies->CFParams.present) { |
| eseBcnReportMandatoryIe.cfPresent = 1; |
| convert_cf_params(pMac, &eseBcnReportMandatoryIe.cfParamSet, |
| &pBies->CFParams); |
| numBytes += 1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX; |
| } |
| |
| if (pBies->IBSSParams.present) { |
| eseBcnReportMandatoryIe.ibssParamPresent = 1; |
| eseBcnReportMandatoryIe.ibssParamSet.atim = |
| pBies->IBSSParams.atim; |
| numBytes += 1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX; |
| } |
| |
| if (pBies->TIM.present) { |
| eseBcnReportMandatoryIe.timPresent = 1; |
| eseBcnReportMandatoryIe.tim.dtimCount = pBies->TIM.dtim_count; |
| eseBcnReportMandatoryIe.tim.dtimPeriod = pBies->TIM.dtim_period; |
| eseBcnReportMandatoryIe.tim.bitmapControl = pBies->TIM.bmpctl; |
| /* As per the ESE spec, May truncate and report first 4 octets only */ |
| numBytes += 1 + 1 + SIR_MAC_TIM_EID_MIN; |
| } |
| |
| if (pBies->RRMEnabledCap.present) { |
| eseBcnReportMandatoryIe.rrmPresent = 1; |
| qdf_mem_copy(&eseBcnReportMandatoryIe.rmEnabledCapabilities, |
| &pBies->RRMEnabledCap, |
| sizeof(tDot11fIERRMEnabledCap)); |
| numBytes += 1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX; |
| } |
| |
| *outIeBuf = qdf_mem_malloc(numBytes); |
| if (NULL == *outIeBuf) { |
| pe_err("Memory Allocation failure"); |
| qdf_mem_free(pBies); |
| return QDF_STATUS_E_NOMEM; |
| } |
| pos = *outIeBuf; |
| *pOutIeLen = numBytes; |
| freeBytes = numBytes; |
| |
| /* Start filling the output Ie with Mandatory IE information */ |
| /* Fill SSID IE */ |
| if (eseBcnReportMandatoryIe.ssidPresent) { |
| if (freeBytes < (1 + 1 + eseBcnReportMandatoryIe.ssId.length)) { |
| pe_err("Insufficient memory to copy SSID"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| goto err_bcnrep; |
| } |
| *pos = SIR_MAC_SSID_EID; |
| pos++; |
| *pos = eseBcnReportMandatoryIe.ssId.length; |
| pos++; |
| qdf_mem_copy(pos, |
| (uint8_t *) eseBcnReportMandatoryIe.ssId.ssId, |
| eseBcnReportMandatoryIe.ssId.length); |
| pos += eseBcnReportMandatoryIe.ssId.length; |
| freeBytes -= (1 + 1 + eseBcnReportMandatoryIe.ssId.length); |
| } |
| |
| /* Fill Supported Rates IE */ |
| if (eseBcnReportMandatoryIe.suppRatesPresent) { |
| if (freeBytes < |
| (1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates)) { |
| pe_err("Insufficient memory to copy Rates IE"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| goto err_bcnrep; |
| } |
| if (eseBcnReportMandatoryIe.supportedRates.numRates <= |
| SIR_MAC_RATESET_EID_MAX) { |
| *pos = SIR_MAC_RATESET_EID; |
| pos++; |
| *pos = eseBcnReportMandatoryIe.supportedRates.numRates; |
| pos++; |
| qdf_mem_copy(pos, |
| (uint8_t *) eseBcnReportMandatoryIe.supportedRates. |
| rate, |
| eseBcnReportMandatoryIe.supportedRates.numRates); |
| pos += eseBcnReportMandatoryIe.supportedRates.numRates; |
| freeBytes -= |
| (1 + 1 + |
| eseBcnReportMandatoryIe.supportedRates.numRates); |
| } |
| } |
| |
| /* Fill FH Parameter set IE */ |
| if (eseBcnReportMandatoryIe.fhParamPresent) { |
| if (freeBytes < (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX)) { |
| pe_err("Insufficient memory to copy FHIE"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| goto err_bcnrep; |
| } |
| *pos = SIR_MAC_FH_PARAM_SET_EID; |
| pos++; |
| *pos = SIR_MAC_FH_PARAM_SET_EID_MAX; |
| pos++; |
| qdf_mem_copy(pos, |
| (uint8_t *) &eseBcnReportMandatoryIe.fhParamSet, |
| SIR_MAC_FH_PARAM_SET_EID_MAX); |
| pos += SIR_MAC_FH_PARAM_SET_EID_MAX; |
| freeBytes -= (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX); |
| } |
| |
| /* Fill DS Parameter set IE */ |
| if (eseBcnReportMandatoryIe.dsParamsPresent) { |
| if (freeBytes < (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX)) { |
| pe_err("Insufficient memory to copy DS IE"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| goto err_bcnrep; |
| } |
| *pos = SIR_MAC_DS_PARAM_SET_EID; |
| pos++; |
| *pos = SIR_MAC_DS_PARAM_SET_EID_MAX; |
| pos++; |
| *pos = eseBcnReportMandatoryIe.dsParamSet.channelNumber; |
| pos += SIR_MAC_DS_PARAM_SET_EID_MAX; |
| freeBytes -= (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX); |
| } |
| |
| /* Fill CF Parameter set */ |
| if (eseBcnReportMandatoryIe.cfPresent) { |
| if (freeBytes < (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX)) { |
| pe_err("Insufficient memory to copy CF IE"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| goto err_bcnrep; |
| } |
| *pos = SIR_MAC_CF_PARAM_SET_EID; |
| pos++; |
| *pos = SIR_MAC_CF_PARAM_SET_EID_MAX; |
| pos++; |
| qdf_mem_copy(pos, |
| (uint8_t *) &eseBcnReportMandatoryIe.cfParamSet, |
| SIR_MAC_CF_PARAM_SET_EID_MAX); |
| pos += SIR_MAC_CF_PARAM_SET_EID_MAX; |
| freeBytes -= (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX); |
| } |
| |
| /* Fill IBSS Parameter set IE */ |
| if (eseBcnReportMandatoryIe.ibssParamPresent) { |
| if (freeBytes < (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX)) { |
| pe_err("Insufficient memory to copy IBSS IE"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| goto err_bcnrep; |
| } |
| *pos = SIR_MAC_IBSS_PARAM_SET_EID; |
| pos++; |
| *pos = SIR_MAC_IBSS_PARAM_SET_EID_MAX; |
| pos++; |
| qdf_mem_copy(pos, |
| (uint8_t *) &eseBcnReportMandatoryIe.ibssParamSet. |
| atim, SIR_MAC_IBSS_PARAM_SET_EID_MAX); |
| pos += SIR_MAC_IBSS_PARAM_SET_EID_MAX; |
| freeBytes -= (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX); |
| } |
| |
| /* Fill TIM IE */ |
| if (eseBcnReportMandatoryIe.timPresent) { |
| if (freeBytes < (1 + 1 + SIR_MAC_TIM_EID_MIN)) { |
| pe_err("Insufficient memory to copy TIM IE"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| goto err_bcnrep; |
| } |
| *pos = SIR_MAC_TIM_EID; |
| pos++; |
| *pos = SIR_MAC_TIM_EID_MIN; |
| pos++; |
| qdf_mem_copy(pos, |
| (uint8_t *) &eseBcnReportMandatoryIe.tim, |
| SIR_MAC_TIM_EID_MIN); |
| pos += SIR_MAC_TIM_EID_MIN; |
| freeBytes -= (1 + 1 + SIR_MAC_TIM_EID_MIN); |
| } |
| |
| /* Fill RM Capability IE */ |
| if (eseBcnReportMandatoryIe.rrmPresent) { |
| if (freeBytes < (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX)) { |
| pe_err("Insufficient memory to copy RRM IE"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| goto err_bcnrep; |
| } |
| *pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID; |
| pos++; |
| *pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX; |
| pos++; |
| qdf_mem_copy(pos, |
| (uint8_t *) &eseBcnReportMandatoryIe. |
| rmEnabledCapabilities, |
| SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX); |
| freeBytes -= (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX); |
| } |
| |
| if (freeBytes != 0) { |
| pe_err("Mismatch in allocation and copying of IE in Bcn Rep"); |
| retStatus = QDF_STATUS_E_FAILURE; |
| } |
| |
| err_bcnrep: |
| /* The message counter would not be incremented in case of |
| * returning failure and hence next time, this function gets |
| * called, it would be using the same msg ctr for a different |
| * BSS.So, it is good to clear the memory allocated for a BSS |
| * that is returning failure.On success, the caller would take |
| * care of freeing up the memory*/ |
| if (retStatus == QDF_STATUS_E_FAILURE) { |
| qdf_mem_free(*outIeBuf); |
| *outIeBuf = NULL; |
| } |
| |
| qdf_mem_free(pBies); |
| return retStatus; |
| } |
| |
| #endif /* FEATURE_WLAN_ESE */ |
| |
| #ifdef WLAN_FEATURE_11AX_BSS_COLOR |
| static void update_bss_color_change_from_beacon_ies(tDot11fBeaconIEs *bcn_ies, |
| tpSirProbeRespBeacon bcn_struct) |
| { |
| if (bcn_ies->bss_color_change.present) { |
| qdf_mem_copy(&bcn_struct->vendor_he_bss_color_change, |
| &bcn_ies->bss_color_change, |
| sizeof(tDot11fIEbss_color_change)); |
| } |
| } |
| #else |
| static inline void update_bss_color_change_from_beacon_ies( |
| tDot11fBeaconIEs *bcn_ies, |
| tpSirProbeRespBeacon bcn_struct) |
| {} |
| #endif |
| |
| QDF_STATUS |
| sir_parse_beacon_ie(tpAniSirGlobal pMac, |
| tpSirProbeRespBeacon pBeaconStruct, |
| uint8_t *pPayload, uint32_t nPayload) |
| { |
| tDot11fBeaconIEs *pBies; |
| uint32_t status; |
| |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0); |
| |
| pBies = qdf_mem_malloc(sizeof(tDot11fBeaconIEs)); |
| if (NULL == pBies) { |
| pe_err("Failed to allocate memory"); |
| return QDF_STATUS_E_NOMEM; |
| } |
| qdf_mem_zero(pBies, sizeof(tDot11fBeaconIEs)); |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_beacon_i_es(pMac, pPayload, nPayload, |
| pBies, false); |
| |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):", |
| status, nPayload); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pPayload, nPayload); |
| qdf_mem_free(pBies); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):", |
| status, nPayload); |
| } |
| /* & "transliterate" from a 'tDot11fBeaconIEs' to a 'tSirProbeRespBeacon'... */ |
| if (!pBies->SSID.present) { |
| pe_debug("Mandatory IE SSID not present!"); |
| } else { |
| pBeaconStruct->ssidPresent = 1; |
| convert_ssid(pMac, &pBeaconStruct->ssId, &pBies->SSID); |
| } |
| |
| if (!pBies->SuppRates.present) { |
| pe_debug_rl("Mandatory IE Supported Rates not present!"); |
| } else { |
| pBeaconStruct->suppRatesPresent = 1; |
| convert_supp_rates(pMac, &pBeaconStruct->supportedRates, |
| &pBies->SuppRates); |
| } |
| |
| if (pBies->ExtSuppRates.present) { |
| pBeaconStruct->extendedRatesPresent = 1; |
| convert_ext_supp_rates(pMac, &pBeaconStruct->extendedRates, |
| &pBies->ExtSuppRates); |
| } |
| |
| if (pBies->CFParams.present) { |
| pBeaconStruct->cfPresent = 1; |
| convert_cf_params(pMac, &pBeaconStruct->cfParamSet, |
| &pBies->CFParams); |
| } |
| |
| if (pBies->TIM.present) { |
| pBeaconStruct->timPresent = 1; |
| convert_tim(pMac, &pBeaconStruct->tim, &pBies->TIM); |
| } |
| |
| if (pBies->Country.present) { |
| pBeaconStruct->countryInfoPresent = 1; |
| convert_country(pMac, &pBeaconStruct->countryInfoParam, |
| &pBies->Country); |
| } |
| /* 11h IEs */ |
| if (pBies->TPCReport.present) { |
| pBeaconStruct->tpcReportPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->tpcReport, |
| &pBies->TPCReport, sizeof(tDot11fIETPCReport)); |
| } |
| |
| if (pBies->PowerConstraints.present) { |
| pBeaconStruct->powerConstraintPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->localPowerConstraint, |
| &pBies->PowerConstraints, |
| sizeof(tDot11fIEPowerConstraints)); |
| } |
| #ifdef FEATURE_WLAN_ESE |
| if (pBies->ESEVersion.present) |
| pBeaconStruct->is_ese_ver_ie_present = 1; |
| if (pBies->ESETxmitPower.present) { |
| pBeaconStruct->eseTxPwr.present = 1; |
| pBeaconStruct->eseTxPwr.power_limit = |
| pBies->ESETxmitPower.power_limit; |
| } |
| if (pBies->QBSSLoad.present) { |
| qdf_mem_copy(&pBeaconStruct->QBSSLoad, &pBies->QBSSLoad, |
| sizeof(tDot11fIEQBSSLoad)); |
| } |
| #endif |
| |
| if (pBies->EDCAParamSet.present) { |
| pBeaconStruct->edcaPresent = 1; |
| convert_edca_param(pMac, &pBeaconStruct->edcaParams, |
| &pBies->EDCAParamSet); |
| } |
| /* QOS Capabilities: */ |
| if (pBies->QOSCapsAp.present) { |
| pBeaconStruct->qosCapabilityPresent = 1; |
| convert_qos_caps(pMac, &pBeaconStruct->qosCapability, |
| &pBies->QOSCapsAp); |
| } |
| |
| if (pBies->ChanSwitchAnn.present) { |
| pBeaconStruct->channelSwitchPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->channelSwitchIE, |
| &pBies->ChanSwitchAnn, |
| sizeof(pBeaconStruct->channelSwitchIE)); |
| } |
| |
| if (pBies->SuppOperatingClasses.present) { |
| pBeaconStruct->supp_operating_class_present = 1; |
| qdf_mem_copy(&pBeaconStruct->supp_operating_classes, |
| &pBies->SuppOperatingClasses, |
| sizeof(tDot11fIESuppOperatingClasses)); |
| } |
| |
| if (pBies->ext_chan_switch_ann.present) { |
| pBeaconStruct->ext_chan_switch_present = 1; |
| qdf_mem_copy(&pBeaconStruct->ext_chan_switch, |
| &pBies->ext_chan_switch_ann, |
| sizeof(tDot11fIEext_chan_switch_ann)); |
| } |
| |
| if (pBies->sec_chan_offset_ele.present) { |
| pBeaconStruct->sec_chan_offset_present = 1; |
| qdf_mem_copy(&pBeaconStruct->sec_chan_offset, |
| &pBies->sec_chan_offset_ele, |
| sizeof(pBeaconStruct->sec_chan_offset)); |
| } |
| |
| if (pBies->Quiet.present) { |
| pBeaconStruct->quietIEPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->quietIE, &pBies->Quiet, |
| sizeof(tDot11fIEQuiet)); |
| } |
| |
| if (pBies->HTCaps.present) { |
| qdf_mem_copy(&pBeaconStruct->HTCaps, &pBies->HTCaps, |
| sizeof(tDot11fIEHTCaps)); |
| } |
| |
| if (pBies->HTInfo.present) { |
| qdf_mem_copy(&pBeaconStruct->HTInfo, &pBies->HTInfo, |
| sizeof(tDot11fIEHTInfo)); |
| } |
| |
| if (pBies->DSParams.present) { |
| pBeaconStruct->dsParamsPresent = 1; |
| pBeaconStruct->channelNumber = pBies->DSParams.curr_channel; |
| } else if (pBies->HTInfo.present) { |
| pBeaconStruct->channelNumber = pBies->HTInfo.primaryChannel; |
| } |
| |
| if (pBies->RSN.present) { |
| pBeaconStruct->rsnPresent = 1; |
| convert_rsn(pMac, &pBeaconStruct->rsn, &pBies->RSN); |
| } |
| |
| if (pBies->WPA.present) { |
| pBeaconStruct->wpaPresent = 1; |
| convert_wpa(pMac, &pBeaconStruct->wpa, &pBies->WPA); |
| } |
| |
| if (pBies->WMMParams.present) { |
| pBeaconStruct->wmeEdcaPresent = 1; |
| convert_wmm_params(pMac, &pBeaconStruct->edcaParams, |
| &pBies->WMMParams); |
| } |
| |
| if (pBies->WMMInfoAp.present) { |
| pBeaconStruct->wmeInfoPresent = 1; |
| } |
| |
| if (pBies->WMMCaps.present) { |
| pBeaconStruct->wsmCapablePresent = 1; |
| } |
| |
| if (pBies->ERPInfo.present) { |
| pBeaconStruct->erpPresent = 1; |
| convert_erp_info(pMac, &pBeaconStruct->erpIEInfo, |
| &pBies->ERPInfo); |
| } |
| if (pBies->VHTCaps.present) { |
| pBeaconStruct->VHTCaps.present = 1; |
| qdf_mem_copy(&pBeaconStruct->VHTCaps, &pBies->VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| } |
| if (pBies->VHTOperation.present) { |
| pBeaconStruct->VHTOperation.present = 1; |
| qdf_mem_copy(&pBeaconStruct->VHTOperation, &pBies->VHTOperation, |
| sizeof(tDot11fIEVHTOperation)); |
| } |
| if (pBies->VHTExtBssLoad.present) { |
| pBeaconStruct->VHTExtBssLoad.present = 1; |
| qdf_mem_copy(&pBeaconStruct->VHTExtBssLoad, |
| &pBies->VHTExtBssLoad, |
| sizeof(tDot11fIEVHTExtBssLoad)); |
| } |
| if (pBies->OperatingMode.present) { |
| pBeaconStruct->OperatingMode.present = 1; |
| qdf_mem_copy(&pBeaconStruct->OperatingMode, |
| &pBies->OperatingMode, |
| sizeof(tDot11fIEOperatingMode)); |
| } |
| if (pBies->MobilityDomain.present) { |
| pBeaconStruct->mdiePresent = 1; |
| qdf_mem_copy(pBeaconStruct->mdie, &pBies->MobilityDomain.MDID, |
| SIR_MDIE_SIZE); |
| } |
| |
| pBeaconStruct->Vendor1IEPresent = pBies->Vendor1IE.present; |
| pBeaconStruct->Vendor3IEPresent = pBies->Vendor3IE.present; |
| pBeaconStruct->vendor_vht_ie.present = pBies->vendor_vht_ie.present; |
| if (pBies->vendor_vht_ie.present) |
| pBeaconStruct->vendor_vht_ie.sub_type = |
| pBies->vendor_vht_ie.sub_type; |
| |
| if (pBies->vendor_vht_ie.VHTCaps.present) { |
| pBeaconStruct->vendor_vht_ie.VHTCaps.present = 1; |
| qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTCaps, |
| &pBies->vendor_vht_ie.VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| } |
| if (pBies->vendor_vht_ie.VHTOperation.present) { |
| pBeaconStruct->vendor_vht_ie.VHTOperation.present = 1; |
| qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTOperation, |
| &pBies->vendor_vht_ie.VHTOperation, |
| sizeof(tDot11fIEVHTOperation)); |
| } |
| if (pBies->ExtCap.present) { |
| qdf_mem_copy(&pBeaconStruct->ext_cap, &pBies->ExtCap, |
| sizeof(tDot11fIEExtCap)); |
| } |
| /* Update HS 2.0 Information Element */ |
| if (pBies->hs20vendor_ie.present) { |
| pe_debug("HS20 Indication Element Present, rel#:%u, id:%u", |
| pBies->hs20vendor_ie.release_num, |
| pBies->hs20vendor_ie.hs_id_present); |
| qdf_mem_copy(&pBeaconStruct->hs20vendor_ie, |
| &pBies->hs20vendor_ie, |
| sizeof(tDot11fIEhs20vendor_ie) - |
| sizeof(pBies->hs20vendor_ie.hs_id)); |
| if (pBies->hs20vendor_ie.hs_id_present) |
| qdf_mem_copy(&pBeaconStruct->hs20vendor_ie.hs_id, |
| &pBies->hs20vendor_ie.hs_id, |
| sizeof(pBies->hs20vendor_ie.hs_id)); |
| } |
| |
| if (pBies->MBO_IE.present) { |
| pBeaconStruct->MBO_IE_present = true; |
| if (pBies->MBO_IE.cellular_data_cap.present) |
| pBeaconStruct->MBO_capability = |
| pBies->MBO_IE.cellular_data_cap.cellular_connectivity; |
| |
| if (pBies->MBO_IE.assoc_disallowed.present) { |
| pBeaconStruct->assoc_disallowed = true; |
| pBeaconStruct->assoc_disallowed_reason = |
| pBies->MBO_IE.assoc_disallowed.reason_code; |
| } |
| } |
| |
| if (pBies->QCN_IE.present) { |
| pBeaconStruct->QCN_IE.is_present = true; |
| if (pBies->QCN_IE.version[0] == QCN_IE_VERSION_SUBATTR_ID) { |
| pBeaconStruct->QCN_IE.version |
| = pBies->QCN_IE.version[2]; |
| pBeaconStruct->QCN_IE.sub_version |
| = pBies->QCN_IE.version[3]; |
| } |
| } |
| |
| if (pBies->he_cap.present) { |
| qdf_mem_copy(&pBeaconStruct->he_cap, &pBies->he_cap, |
| sizeof(tDot11fIEhe_cap)); |
| } |
| if (pBies->he_op.present) { |
| qdf_mem_copy(&pBeaconStruct->he_op, &pBies->he_op, |
| sizeof(tDot11fIEhe_op)); |
| } |
| |
| update_bss_color_change_from_beacon_ies(pBies, pBeaconStruct); |
| |
| qdf_mem_free(pBies); |
| return QDF_STATUS_SUCCESS; |
| } /* End sir_parse_beacon_ie. */ |
| |
| #ifdef WLAN_FEATURE_11AX_BSS_COLOR |
| static void convert_bcon_bss_color_change_ie(tDot11fBeacon *bcn_frm, |
| tpSirProbeRespBeacon bcn_struct) |
| { |
| if (bcn_frm->bss_color_change.present) { |
| pe_debug("11AX: HE BSS color change present"); |
| qdf_mem_copy(&bcn_struct->vendor_he_bss_color_change, |
| &bcn_frm->bss_color_change, |
| sizeof(tDot11fIEbss_color_change)); |
| } |
| } |
| #else |
| static inline void convert_bcon_bss_color_change_ie(tDot11fBeacon *bcn_frm, |
| tpSirProbeRespBeacon bcn_struct) |
| {} |
| #endif |
| |
| QDF_STATUS |
| sir_convert_beacon_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| tpSirProbeRespBeacon pBeaconStruct) |
| { |
| tDot11fBeacon *pBeacon; |
| uint32_t status, nPayload; |
| uint8_t *pPayload; |
| tpSirMacMgmtHdr pHdr; |
| uint8_t mappedRXCh; |
| |
| pPayload = WMA_GET_RX_MPDU_DATA(pFrame); |
| nPayload = WMA_GET_RX_PAYLOAD_LEN(pFrame); |
| pHdr = WMA_GET_RX_MAC_HEADER(pFrame); |
| mappedRXCh = WMA_GET_RX_CH(pFrame); |
| |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0); |
| |
| pBeacon = qdf_mem_malloc(sizeof(tDot11fBeacon)); |
| if (NULL == pBeacon) { |
| pe_err("Failed to allocate memory"); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| /* get the MAC address out of the BD, */ |
| qdf_mem_copy(pBeaconStruct->bssid, pHdr->sa, 6); |
| |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_beacon(pMac, pPayload, nPayload, pBeacon, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse Beacon IEs (0x%08x, %d bytes):", |
| status, nPayload); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, |
| pPayload, nPayload); |
| qdf_mem_free(pBeacon); |
| return QDF_STATUS_E_FAILURE; |
| } |
| /* & "transliterate" from a 'tDot11fBeacon' to a 'tSirProbeRespBeacon'... */ |
| /* Timestamp */ |
| qdf_mem_copy((uint8_t *) pBeaconStruct->timeStamp, |
| (uint8_t *) &pBeacon->TimeStamp, |
| sizeof(tSirMacTimeStamp)); |
| |
| /* Beacon Interval */ |
| pBeaconStruct->beaconInterval = pBeacon->BeaconInterval.interval; |
| |
| /* Capabilities */ |
| pBeaconStruct->capabilityInfo.ess = pBeacon->Capabilities.ess; |
| pBeaconStruct->capabilityInfo.ibss = pBeacon->Capabilities.ibss; |
| pBeaconStruct->capabilityInfo.cfPollable = |
| pBeacon->Capabilities.cfPollable; |
| pBeaconStruct->capabilityInfo.cfPollReq = |
| pBeacon->Capabilities.cfPollReq; |
| pBeaconStruct->capabilityInfo.privacy = pBeacon->Capabilities.privacy; |
| pBeaconStruct->capabilityInfo.shortPreamble = |
| pBeacon->Capabilities.shortPreamble; |
| pBeaconStruct->capabilityInfo.pbcc = pBeacon->Capabilities.pbcc; |
| pBeaconStruct->capabilityInfo.channelAgility = |
| pBeacon->Capabilities.channelAgility; |
| pBeaconStruct->capabilityInfo.spectrumMgt = |
| pBeacon->Capabilities.spectrumMgt; |
| pBeaconStruct->capabilityInfo.qos = pBeacon->Capabilities.qos; |
| pBeaconStruct->capabilityInfo.shortSlotTime = |
| pBeacon->Capabilities.shortSlotTime; |
| pBeaconStruct->capabilityInfo.apsd = pBeacon->Capabilities.apsd; |
| pBeaconStruct->capabilityInfo.rrm = pBeacon->Capabilities.rrm; |
| pBeaconStruct->capabilityInfo.dsssOfdm = pBeacon->Capabilities.dsssOfdm; |
| pBeaconStruct->capabilityInfo.delayedBA = |
| pBeacon->Capabilities.delayedBA; |
| pBeaconStruct->capabilityInfo.immediateBA = |
| pBeacon->Capabilities.immediateBA; |
| |
| if (!pBeacon->SSID.present) { |
| pe_debug("Mandatory IE SSID not present!"); |
| } else { |
| pBeaconStruct->ssidPresent = 1; |
| convert_ssid(pMac, &pBeaconStruct->ssId, &pBeacon->SSID); |
| } |
| |
| if (!pBeacon->SuppRates.present) { |
| pe_debug_rl("Mandatory IE Supported Rates not present!"); |
| } else { |
| pBeaconStruct->suppRatesPresent = 1; |
| convert_supp_rates(pMac, &pBeaconStruct->supportedRates, |
| &pBeacon->SuppRates); |
| } |
| |
| if (pBeacon->ExtSuppRates.present) { |
| pBeaconStruct->extendedRatesPresent = 1; |
| convert_ext_supp_rates(pMac, &pBeaconStruct->extendedRates, |
| &pBeacon->ExtSuppRates); |
| } |
| |
| if (pBeacon->CFParams.present) { |
| pBeaconStruct->cfPresent = 1; |
| convert_cf_params(pMac, &pBeaconStruct->cfParamSet, |
| &pBeacon->CFParams); |
| } |
| |
| if (pBeacon->TIM.present) { |
| pBeaconStruct->timPresent = 1; |
| convert_tim(pMac, &pBeaconStruct->tim, &pBeacon->TIM); |
| } |
| |
| if (pBeacon->Country.present) { |
| pBeaconStruct->countryInfoPresent = 1; |
| convert_country(pMac, &pBeaconStruct->countryInfoParam, |
| &pBeacon->Country); |
| } |
| /* QOS Capabilities: */ |
| if (pBeacon->QOSCapsAp.present) { |
| pBeaconStruct->qosCapabilityPresent = 1; |
| convert_qos_caps(pMac, &pBeaconStruct->qosCapability, |
| &pBeacon->QOSCapsAp); |
| } |
| |
| if (pBeacon->EDCAParamSet.present) { |
| pBeaconStruct->edcaPresent = 1; |
| convert_edca_param(pMac, &pBeaconStruct->edcaParams, |
| &pBeacon->EDCAParamSet); |
| } |
| |
| if (pBeacon->ChanSwitchAnn.present) { |
| pBeaconStruct->channelSwitchPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->channelSwitchIE, |
| &pBeacon->ChanSwitchAnn, |
| sizeof(pBeaconStruct->channelSwitchIE)); |
| } |
| |
| if (pBeacon->ext_chan_switch_ann.present) { |
| pBeaconStruct->ext_chan_switch_present = 1; |
| qdf_mem_copy(&pBeaconStruct->ext_chan_switch, |
| &pBeacon->ext_chan_switch_ann, |
| sizeof(tDot11fIEext_chan_switch_ann)); |
| } |
| |
| if (pBeacon->sec_chan_offset_ele.present) { |
| pBeaconStruct->sec_chan_offset_present = 1; |
| qdf_mem_copy(&pBeaconStruct->sec_chan_offset, |
| &pBeacon->sec_chan_offset_ele, |
| sizeof(pBeaconStruct->sec_chan_offset)); |
| } |
| |
| if (pBeacon->TPCReport.present) { |
| pBeaconStruct->tpcReportPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->tpcReport, &pBeacon->TPCReport, |
| sizeof(tDot11fIETPCReport)); |
| } |
| |
| if (pBeacon->PowerConstraints.present) { |
| pBeaconStruct->powerConstraintPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->localPowerConstraint, |
| &pBeacon->PowerConstraints, |
| sizeof(tDot11fIEPowerConstraints)); |
| } |
| |
| if (pBeacon->Quiet.present) { |
| pBeaconStruct->quietIEPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->quietIE, &pBeacon->Quiet, |
| sizeof(tDot11fIEQuiet)); |
| } |
| |
| if (pBeacon->HTCaps.present) { |
| qdf_mem_copy(&pBeaconStruct->HTCaps, &pBeacon->HTCaps, |
| sizeof(tDot11fIEHTCaps)); |
| } |
| |
| if (pBeacon->HTInfo.present) { |
| qdf_mem_copy(&pBeaconStruct->HTInfo, &pBeacon->HTInfo, |
| sizeof(tDot11fIEHTInfo)); |
| |
| } |
| |
| if (pBeacon->DSParams.present) { |
| pBeaconStruct->dsParamsPresent = 1; |
| pBeaconStruct->channelNumber = pBeacon->DSParams.curr_channel; |
| } else if (pBeacon->HTInfo.present) { |
| pBeaconStruct->channelNumber = pBeacon->HTInfo.primaryChannel; |
| } else { |
| pBeaconStruct->channelNumber = mappedRXCh; |
| pe_debug_rl("In Beacon No Channel info"); |
| } |
| |
| if (pBeacon->RSN.present) { |
| pBeaconStruct->rsnPresent = 1; |
| convert_rsn(pMac, &pBeaconStruct->rsn, &pBeacon->RSN); |
| } |
| |
| if (pBeacon->WPA.present) { |
| pBeaconStruct->wpaPresent = 1; |
| convert_wpa(pMac, &pBeaconStruct->wpa, &pBeacon->WPA); |
| } |
| |
| if (pBeacon->WMMParams.present) { |
| pBeaconStruct->wmeEdcaPresent = 1; |
| convert_wmm_params(pMac, &pBeaconStruct->edcaParams, |
| &pBeacon->WMMParams); |
| } |
| |
| if (pBeacon->WMMInfoAp.present) { |
| pBeaconStruct->wmeInfoPresent = 1; |
| pe_debug("WMM Info present in Beacon Frame!"); |
| } |
| |
| if (pBeacon->WMMCaps.present) { |
| pBeaconStruct->wsmCapablePresent = 1; |
| } |
| |
| if (pBeacon->ERPInfo.present) { |
| pBeaconStruct->erpPresent = 1; |
| convert_erp_info(pMac, &pBeaconStruct->erpIEInfo, |
| &pBeacon->ERPInfo); |
| } |
| if (pBeacon->MobilityDomain.present) { |
| /* MobilityDomain */ |
| pBeaconStruct->mdiePresent = 1; |
| qdf_mem_copy((uint8_t *) &(pBeaconStruct->mdie[0]), |
| (uint8_t *) &(pBeacon->MobilityDomain.MDID), |
| sizeof(uint16_t)); |
| pBeaconStruct->mdie[2] = |
| ((pBeacon->MobilityDomain.overDSCap << 0) | (pBeacon-> |
| MobilityDomain. |
| resourceReqCap |
| << 1)); |
| |
| } |
| |
| #ifdef FEATURE_WLAN_ESE |
| if (pBeacon->ESEVersion.present) |
| pBeaconStruct->is_ese_ver_ie_present = 1; |
| if (pBeacon->ESETxmitPower.present) { |
| /* copy ESE TPC info element */ |
| pBeaconStruct->eseTxPwr.present = 1; |
| qdf_mem_copy(&pBeaconStruct->eseTxPwr, |
| &pBeacon->ESETxmitPower, |
| sizeof(tDot11fIEESETxmitPower)); |
| } |
| if (pBeacon->QBSSLoad.present) { |
| qdf_mem_copy(&pBeaconStruct->QBSSLoad, |
| &pBeacon->QBSSLoad, sizeof(tDot11fIEQBSSLoad)); |
| } |
| #endif |
| if (pBeacon->VHTCaps.present) { |
| qdf_mem_copy(&pBeaconStruct->VHTCaps, &pBeacon->VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| } |
| if (pBeacon->VHTOperation.present) { |
| qdf_mem_copy(&pBeaconStruct->VHTOperation, |
| &pBeacon->VHTOperation, |
| sizeof(tDot11fIEVHTOperation)); |
| } |
| if (pBeacon->VHTExtBssLoad.present) { |
| qdf_mem_copy(&pBeaconStruct->VHTExtBssLoad, |
| &pBeacon->VHTExtBssLoad, |
| sizeof(tDot11fIEVHTExtBssLoad)); |
| } |
| if (pBeacon->OperatingMode.present) { |
| qdf_mem_copy(&pBeaconStruct->OperatingMode, |
| &pBeacon->OperatingMode, |
| sizeof(tDot11fIEOperatingMode)); |
| } |
| if (pBeacon->WiderBWChanSwitchAnn.present) { |
| pBeaconStruct->WiderBWChanSwitchAnnPresent = 1; |
| qdf_mem_copy(&pBeaconStruct->WiderBWChanSwitchAnn, |
| &pBeacon->WiderBWChanSwitchAnn, |
| sizeof(tDot11fIEWiderBWChanSwitchAnn)); |
| } |
| /* IBSS Peer Params */ |
| if (pBeacon->IBSSParams.present) { |
| pBeaconStruct->IBSSParams.present = 1; |
| qdf_mem_copy(&pBeaconStruct->IBSSParams, &pBeacon->IBSSParams, |
| sizeof(tDot11fIEIBSSParams)); |
| } |
| |
| pBeaconStruct->Vendor1IEPresent = pBeacon->Vendor1IE.present; |
| pBeaconStruct->Vendor3IEPresent = pBeacon->Vendor3IE.present; |
| |
| pBeaconStruct->vendor_vht_ie.present = pBeacon->vendor_vht_ie.present; |
| if (pBeacon->vendor_vht_ie.present) { |
| pBeaconStruct->vendor_vht_ie.sub_type = |
| pBeacon->vendor_vht_ie.sub_type; |
| } |
| |
| if (pBeacon->vendor_vht_ie.VHTCaps.present) { |
| qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTCaps, |
| &pBeacon->vendor_vht_ie.VHTCaps, |
| sizeof(tDot11fIEVHTCaps)); |
| } |
| if (pBeacon->vendor_vht_ie.VHTOperation.present) { |
| qdf_mem_copy(&pBeaconStruct->vendor_vht_ie.VHTOperation, |
| &pBeacon->VHTOperation, |
| sizeof(tDot11fIEVHTOperation)); |
| } |
| /* Update HS 2.0 Information Element */ |
| if (pBeacon->hs20vendor_ie.present) { |
| qdf_mem_copy(&pBeaconStruct->hs20vendor_ie, |
| &pBeacon->hs20vendor_ie, |
| sizeof(tDot11fIEhs20vendor_ie) - |
| sizeof(pBeacon->hs20vendor_ie.hs_id)); |
| if (pBeacon->hs20vendor_ie.hs_id_present) |
| qdf_mem_copy(&pBeaconStruct->hs20vendor_ie.hs_id, |
| &pBeacon->hs20vendor_ie.hs_id, |
| sizeof(pBeacon->hs20vendor_ie.hs_id)); |
| } |
| #ifdef FEATURE_AP_MCC_CH_AVOIDANCE |
| if (pBeacon->QComVendorIE.present) { |
| pBeaconStruct->AvoidChannelIE.present = |
| pBeacon->QComVendorIE.present; |
| pBeaconStruct->AvoidChannelIE.type = |
| pBeacon->QComVendorIE.type; |
| pBeaconStruct->AvoidChannelIE.channel = |
| pBeacon->QComVendorIE.channel; |
| } |
| #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ |
| if (pBeacon->OBSSScanParameters.present) { |
| qdf_mem_copy(&pBeaconStruct->obss_scanparams, |
| &pBeacon->OBSSScanParameters, |
| sizeof(struct sDot11fIEOBSSScanParameters)); |
| } |
| if (pBeacon->MBO_IE.present) { |
| pBeaconStruct->MBO_IE_present = true; |
| if (pBeacon->MBO_IE.cellular_data_cap.present) |
| pBeaconStruct->MBO_capability = |
| pBeacon->MBO_IE.cellular_data_cap.cellular_connectivity; |
| |
| if (pBeacon->MBO_IE.assoc_disallowed.present) { |
| pBeaconStruct->assoc_disallowed = true; |
| pBeaconStruct->assoc_disallowed_reason = |
| pBeacon->MBO_IE.assoc_disallowed.reason_code; |
| } |
| } |
| |
| if (pBeacon->QCN_IE.present) { |
| pBeaconStruct->QCN_IE.is_present = true; |
| if (pBeacon->QCN_IE.version[0] |
| == QCN_IE_VERSION_SUBATTR_ID) { |
| pBeaconStruct->QCN_IE.version |
| = pBeacon->QCN_IE.version[2]; |
| pBeaconStruct->QCN_IE.sub_version |
| = pBeacon->QCN_IE.version[3]; |
| } |
| } |
| |
| if (pBeacon->he_cap.present) { |
| pe_debug("11AX: HE cap IE present"); |
| qdf_mem_copy(&pBeaconStruct->he_cap, |
| &pBeacon->he_cap, |
| sizeof(tDot11fIEhe_cap)); |
| } |
| if (pBeacon->he_op.present) { |
| pe_debug("11AX: HE operation IE present"); |
| qdf_mem_copy(&pBeaconStruct->he_op, |
| &pBeacon->he_op, |
| sizeof(tDot11fIEhe_op)); |
| } |
| |
| convert_bcon_bss_color_change_ie(pBeacon, pBeaconStruct); |
| |
| qdf_mem_free(pBeacon); |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_beacon_frame2_struct. */ |
| |
| #ifdef WLAN_FEATURE_FILS_SK |
| /* sir_update_auth_frame2_struct_fils_conf: API to update fils info from auth |
| * packet type 2 |
| * @auth: auth packet pointer received from AP |
| * @auth_frame: data structure needs to be updated |
| * |
| * Return: None |
| */ |
| static void sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth, |
| tpSirMacAuthFrameBody auth_frame) |
| { |
| if (auth->AuthAlgo.algo != SIR_FILS_SK_WITHOUT_PFS) |
| return; |
| |
| if (auth->fils_assoc_delay_info.present) |
| auth_frame->assoc_delay_info = |
| auth->fils_assoc_delay_info.assoc_delay_info; |
| |
| if (auth->fils_session.present) |
| qdf_mem_copy(auth_frame->session, auth->fils_session.session, |
| SIR_FILS_SESSION_LENGTH); |
| |
| if (auth->fils_nonce.present) |
| qdf_mem_copy(auth_frame->nonce, auth->fils_nonce.nonce, |
| SIR_FILS_NONCE_LENGTH); |
| |
| if (auth->fils_wrapped_data.present) { |
| qdf_mem_copy(auth_frame->wrapped_data, |
| auth->fils_wrapped_data.wrapped_data, |
| auth->fils_wrapped_data.num_wrapped_data); |
| auth_frame->wrapped_data_len = |
| auth->fils_wrapped_data.num_wrapped_data; |
| } |
| if (auth->RSNOpaque.present) { |
| qdf_mem_copy(auth_frame->rsn_ie.info, auth->RSNOpaque.data, |
| auth->RSNOpaque.num_data); |
| auth_frame->rsn_ie.length = auth->RSNOpaque.num_data; |
| } |
| } |
| #else |
| static void sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth, |
| tpSirMacAuthFrameBody auth_frame) |
| { } |
| #endif |
| |
| QDF_STATUS |
| sir_convert_auth_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, tpSirMacAuthFrameBody pAuth) |
| { |
| static tDot11fAuthentication auth; |
| uint32_t status; |
| |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pAuth, sizeof(tSirMacAuthFrameBody), 0); |
| |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_authentication(pMac, pFrame, nFrame, |
| &auth, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse an Authentication frame (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking an Authentication frame (0x%08x, %d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fAuthentication' to a 'tSirMacAuthFrameBody'... */ |
| pAuth->authAlgoNumber = auth.AuthAlgo.algo; |
| pAuth->authTransactionSeqNumber = auth.AuthSeqNo.no; |
| pAuth->authStatusCode = auth.Status.status; |
| |
| if (auth.ChallengeText.present) { |
| pAuth->type = SIR_MAC_CHALLENGE_TEXT_EID; |
| pAuth->length = auth.ChallengeText.num_text; |
| qdf_mem_copy(pAuth->challengeText, auth.ChallengeText.text, |
| auth.ChallengeText.num_text); |
| } |
| sir_update_auth_frame2_struct_fils_conf(&auth, pAuth); |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_auth_frame2_struct. */ |
| |
| QDF_STATUS |
| sir_convert_addts_req2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, tSirAddtsReqInfo *pAddTs) |
| { |
| tDot11fAddTSRequest addts = { {0} }; |
| tDot11fWMMAddTSRequest wmmaddts = { {0} }; |
| uint8_t j; |
| uint16_t i; |
| uint32_t status; |
| |
| if (SIR_MAC_QOS_ADD_TS_REQ != *(pFrame + 1)) { |
| pe_err("sir_convert_addts_req2_struct invoked " |
| "with an Action of %d; this is not " |
| "supported & is probably an error", |
| *(pFrame + 1)); |
| return QDF_STATUS_E_FAILURE; |
| } |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pAddTs, sizeof(tSirAddtsReqInfo), 0); |
| |
| /* delegate to the framesc-generated code, */ |
| switch (*pFrame) { |
| case SIR_MAC_ACTION_QOS_MGMT: |
| status = dot11f_unpack_add_ts_request(pMac, pFrame, nFrame, |
| &addts, false); |
| break; |
| case SIR_MAC_ACTION_WME: |
| status = |
| dot11f_unpack_wmm_add_ts_request(pMac, pFrame, nFrame, |
| &wmmaddts, false); |
| break; |
| default: |
| pe_err("sir_convert_addts_req2_struct invoked " |
| "with a Category of %d; this is not" |
| " supported & is probably an error", |
| *pFrame); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse an Add TS Request frame (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking an Add TS Request frame (0x%08x,%d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fAddTSRequest' or a */ |
| /* 'tDot11WMMAddTSRequest' to a 'tSirMacAddtsReqInfo'... */ |
| if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) { |
| pAddTs->dialogToken = addts.DialogToken.token; |
| |
| if (addts.TSPEC.present) { |
| convert_tspec(pMac, &pAddTs->tspec, &addts.TSPEC); |
| } else { |
| pe_err("Mandatory TSPEC element missing in Add TS Request"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (addts.num_TCLAS) { |
| pAddTs->numTclas = (uint8_t) addts.num_TCLAS; |
| |
| for (i = 0U; i < addts.num_TCLAS; ++i) { |
| if (QDF_STATUS_SUCCESS != |
| convert_tclas(pMac, &(pAddTs->tclasInfo[i]), |
| &(addts.TCLAS[i]))) { |
| pe_err("Failed to convert a TCLAS IE"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| } |
| |
| if (addts.TCLASSPROC.present) { |
| pAddTs->tclasProcPresent = 1; |
| pAddTs->tclasProc = addts.TCLASSPROC.processing; |
| } |
| |
| if (addts.WMMTSPEC.present) { |
| pAddTs->wsmTspecPresent = 1; |
| convert_wmmtspec(pMac, &pAddTs->tspec, &addts.WMMTSPEC); |
| } |
| |
| if (addts.num_WMMTCLAS) { |
| j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS); |
| if (SIR_MAC_TCLASIE_MAXNUM < j) |
| j = SIR_MAC_TCLASIE_MAXNUM; |
| |
| for (i = pAddTs->numTclas; i < j; ++i) { |
| if (QDF_STATUS_SUCCESS != |
| convert_wmmtclas(pMac, |
| &(pAddTs->tclasInfo[i]), |
| &(addts.WMMTCLAS[i]))) { |
| pe_err("Failed to convert a TCLAS IE"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| } |
| |
| if (addts.WMMTCLASPROC.present) { |
| pAddTs->tclasProcPresent = 1; |
| pAddTs->tclasProc = addts.WMMTCLASPROC.processing; |
| } |
| |
| if (1 < pAddTs->numTclas && (!pAddTs->tclasProcPresent)) { |
| pe_err("%d TCLAS IE but not TCLASPROC IE", |
| pAddTs->numTclas); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } else { |
| pAddTs->dialogToken = wmmaddts.DialogToken.token; |
| |
| if (wmmaddts.WMMTSPEC.present) { |
| pAddTs->wmeTspecPresent = 1; |
| convert_wmmtspec(pMac, &pAddTs->tspec, |
| &wmmaddts.WMMTSPEC); |
| } else { |
| pe_err("Mandatory WME TSPEC element missing!"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_addts_req2_struct. */ |
| |
| QDF_STATUS |
| sir_convert_addts_rsp2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, tSirAddtsRspInfo *pAddTs) |
| { |
| tDot11fAddTSResponse addts = { {0} }; |
| tDot11fWMMAddTSResponse wmmaddts = { {0} }; |
| uint8_t j; |
| uint16_t i; |
| uint32_t status; |
| |
| if (SIR_MAC_QOS_ADD_TS_RSP != *(pFrame + 1)) { |
| pe_err("sir_convert_addts_rsp2_struct invoked " |
| "with an Action of %d; this is not " |
| "supported & is probably an error", |
| *(pFrame + 1)); |
| return QDF_STATUS_E_FAILURE; |
| } |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pAddTs, sizeof(tSirAddtsRspInfo), 0); |
| qdf_mem_set((uint8_t *) &addts, sizeof(tDot11fAddTSResponse), 0); |
| qdf_mem_set((uint8_t *) &wmmaddts, sizeof(tDot11fWMMAddTSResponse), 0); |
| |
| /* delegate to the framesc-generated code, */ |
| switch (*pFrame) { |
| case SIR_MAC_ACTION_QOS_MGMT: |
| status = |
| dot11f_unpack_add_ts_response(pMac, pFrame, nFrame, |
| &addts, false); |
| break; |
| case SIR_MAC_ACTION_WME: |
| status = |
| dot11f_unpack_wmm_add_ts_response(pMac, pFrame, nFrame, |
| &wmmaddts, false); |
| break; |
| default: |
| pe_err("sir_convert_addts_rsp2_struct invoked " |
| "with a Category of %d; this is not" |
| " supported & is probably an error", |
| *pFrame); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse an Add TS Response frame (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking an Add TS Response frame (0x%08x,%d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fAddTSResponse' or a */ |
| /* 'tDot11WMMAddTSResponse' to a 'tSirMacAddtsRspInfo'... */ |
| if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) { |
| pAddTs->dialogToken = addts.DialogToken.token; |
| pAddTs->status = (tSirMacStatusCodes) addts.Status.status; |
| |
| if (addts.TSDelay.present) { |
| convert_ts_delay(pMac, &pAddTs->delay, &addts.TSDelay); |
| } |
| /* TS Delay is present iff status indicates its presence */ |
| if (eSIR_MAC_TS_NOT_CREATED_STATUS == pAddTs->status |
| && !addts.TSDelay.present) { |
| pe_warn("Missing TSDelay IE"); |
| } |
| |
| if (addts.TSPEC.present) { |
| convert_tspec(pMac, &pAddTs->tspec, &addts.TSPEC); |
| } else { |
| pe_err("Mandatory TSPEC element missing in Add TS Response"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (addts.num_TCLAS) { |
| pAddTs->numTclas = (uint8_t) addts.num_TCLAS; |
| |
| for (i = 0U; i < addts.num_TCLAS; ++i) { |
| if (QDF_STATUS_SUCCESS != |
| convert_tclas(pMac, &(pAddTs->tclasInfo[i]), |
| &(addts.TCLAS[i]))) { |
| pe_err("Failed to convert a TCLAS IE"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| } |
| |
| if (addts.TCLASSPROC.present) { |
| pAddTs->tclasProcPresent = 1; |
| pAddTs->tclasProc = addts.TCLASSPROC.processing; |
| } |
| #ifdef FEATURE_WLAN_ESE |
| if (addts.ESETrafStrmMet.present) { |
| pAddTs->tsmPresent = 1; |
| qdf_mem_copy(&pAddTs->tsmIE.tsid, |
| &addts.ESETrafStrmMet.tsid, |
| sizeof(tSirMacESETSMIE)); |
| } |
| #endif |
| if (addts.Schedule.present) { |
| pAddTs->schedulePresent = 1; |
| convert_schedule(pMac, &pAddTs->schedule, |
| &addts.Schedule); |
| } |
| |
| if (addts.WMMSchedule.present) { |
| pAddTs->schedulePresent = 1; |
| convert_wmm_schedule(pMac, &pAddTs->schedule, |
| &addts.WMMSchedule); |
| } |
| |
| if (addts.WMMTSPEC.present) { |
| pAddTs->wsmTspecPresent = 1; |
| convert_wmmtspec(pMac, &pAddTs->tspec, &addts.WMMTSPEC); |
| } |
| |
| if (addts.num_WMMTCLAS) { |
| j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS); |
| if (SIR_MAC_TCLASIE_MAXNUM < j) |
| j = SIR_MAC_TCLASIE_MAXNUM; |
| |
| for (i = pAddTs->numTclas; i < j; ++i) { |
| if (QDF_STATUS_SUCCESS != |
| convert_wmmtclas(pMac, |
| &(pAddTs->tclasInfo[i]), |
| &(addts.WMMTCLAS[i]))) { |
| pe_err("Failed to convert a TCLAS IE"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| } |
| |
| if (addts.WMMTCLASPROC.present) { |
| pAddTs->tclasProcPresent = 1; |
| pAddTs->tclasProc = addts.WMMTCLASPROC.processing; |
| } |
| |
| if (1 < pAddTs->numTclas && (!pAddTs->tclasProcPresent)) { |
| pe_err("%d TCLAS IE but not TCLASPROC IE", |
| pAddTs->numTclas); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } else { |
| pAddTs->dialogToken = wmmaddts.DialogToken.token; |
| pAddTs->status = |
| (tSirMacStatusCodes) wmmaddts.StatusCode.statusCode; |
| |
| if (wmmaddts.WMMTSPEC.present) { |
| pAddTs->wmeTspecPresent = 1; |
| convert_wmmtspec(pMac, &pAddTs->tspec, |
| &wmmaddts.WMMTSPEC); |
| } else { |
| pe_err("Mandatory WME TSPEC element missing!"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| #ifdef FEATURE_WLAN_ESE |
| if (wmmaddts.ESETrafStrmMet.present) { |
| pAddTs->tsmPresent = 1; |
| qdf_mem_copy(&pAddTs->tsmIE.tsid, |
| &wmmaddts.ESETrafStrmMet.tsid, |
| sizeof(tSirMacESETSMIE)); |
| } |
| #endif |
| |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_addts_rsp2_struct. */ |
| |
| QDF_STATUS |
| sir_convert_delts_req2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, tSirDeltsReqInfo *pDelTs) |
| { |
| tDot11fDelTS delts = { {0} }; |
| tDot11fWMMDelTS wmmdelts = { {0} }; |
| uint32_t status; |
| |
| if (SIR_MAC_QOS_DEL_TS_REQ != *(pFrame + 1)) { |
| pe_err("sirConvertDeltsRsp2Struct invoked " |
| "with an Action of %d; this is not " |
| "supported & is probably an error", |
| *(pFrame + 1)); |
| return QDF_STATUS_E_FAILURE; |
| } |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pDelTs, sizeof(tSirDeltsReqInfo), 0); |
| |
| /* delegate to the framesc-generated code, */ |
| switch (*pFrame) { |
| case SIR_MAC_ACTION_QOS_MGMT: |
| status = dot11f_unpack_del_ts(pMac, pFrame, nFrame, |
| &delts, false); |
| break; |
| case SIR_MAC_ACTION_WME: |
| status = dot11f_unpack_wmm_del_ts(pMac, pFrame, nFrame, |
| &wmmdelts, false); |
| break; |
| default: |
| pe_err("sirConvertDeltsRsp2Struct invoked " |
| "with a Category of %d; this is not" |
| " supported & is probably an error", |
| *pFrame); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse an Del TS Request frame (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking an Del TS Request frame (0x%08x,%d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fDelTSResponse' or a */ |
| /* 'tDot11WMMDelTSResponse' to a 'tSirMacDeltsReqInfo'... */ |
| if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) { |
| pDelTs->tsinfo.traffic.trafficType = |
| (uint16_t) delts.TSInfo.traffic_type; |
| pDelTs->tsinfo.traffic.tsid = (uint16_t) delts.TSInfo.tsid; |
| pDelTs->tsinfo.traffic.direction = |
| (uint16_t) delts.TSInfo.direction; |
| pDelTs->tsinfo.traffic.accessPolicy = |
| (uint16_t) delts.TSInfo.access_policy; |
| pDelTs->tsinfo.traffic.aggregation = |
| (uint16_t) delts.TSInfo.aggregation; |
| pDelTs->tsinfo.traffic.psb = (uint16_t) delts.TSInfo.psb; |
| pDelTs->tsinfo.traffic.userPrio = |
| (uint16_t) delts.TSInfo.user_priority; |
| pDelTs->tsinfo.traffic.ackPolicy = |
| (uint16_t) delts.TSInfo.tsinfo_ack_pol; |
| |
| pDelTs->tsinfo.schedule.schedule = |
| (uint8_t) delts.TSInfo.schedule; |
| } else { |
| if (wmmdelts.WMMTSPEC.present) { |
| pDelTs->wmeTspecPresent = 1; |
| convert_wmmtspec(pMac, &pDelTs->tspec, |
| &wmmdelts.WMMTSPEC); |
| } else { |
| pe_err("Mandatory WME TSPEC element missing!"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_delts_req2_struct. */ |
| |
| QDF_STATUS |
| sir_convert_qos_map_configure_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| uint32_t nFrame, |
| tSirQosMapSet *pQosMapSet) |
| { |
| tDot11fQosMapConfigure mapConfigure; |
| uint32_t status; |
| |
| status = |
| dot11f_unpack_qos_map_configure(pMac, pFrame, nFrame, |
| &mapConfigure, false); |
| if (DOT11F_FAILED(status) || !mapConfigure.QosMapSet.present) { |
| pe_err("Failed to parse Qos Map Configure frame (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking Qos Map Configure frame (0x%08x, %d bytes):", |
| status, nFrame); |
| } |
| pQosMapSet->present = mapConfigure.QosMapSet.present; |
| convert_qos_mapset_frame(pMac, pQosMapSet, &mapConfigure.QosMapSet); |
| lim_log_qos_map_set(pMac, pQosMapSet); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| #ifdef ANI_SUPPORT_11H |
| QDF_STATUS |
| sir_convert_tpc_req_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| tpSirMacTpcReqActionFrame pTpcReqFrame, |
| uint32_t nFrame) |
| { |
| tDot11fTPCRequest req; |
| uint32_t status; |
| |
| qdf_mem_set((uint8_t *) pTpcReqFrame, sizeof(tSirMacTpcReqActionFrame), |
| 0); |
| status = dot11f_unpack_tpc_request(pMac, pFrame, nFrame, &req, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse a TPC Request frame (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking a TPC Request frame (0x%08x, %d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fTPCRequest' to a */ |
| /* 'tSirMacTpcReqActionFrame'... */ |
| pTpcReqFrame->actionHeader.category = req.Category.category; |
| pTpcReqFrame->actionHeader.actionID = req.Action.action; |
| pTpcReqFrame->actionHeader.dialogToken = req.DialogToken.token; |
| if (req.TPCRequest.present) { |
| pTpcReqFrame->type = DOT11F_EID_TPCREQUEST; |
| pTpcReqFrame->length = 0; |
| } else { |
| pe_warn("!!!Rcv TPC Req of inalid type!"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| return QDF_STATUS_SUCCESS; |
| } /* End sir_convert_tpc_req_frame2_struct. */ |
| QDF_STATUS |
| sir_convert_meas_req_frame2_struct(tpAniSirGlobal pMac, |
| uint8_t *pFrame, |
| tpSirMacMeasReqActionFrame pMeasReqFrame, |
| uint32_t nFrame) |
| { |
| tDot11fMeasurementRequest mr; |
| uint32_t status; |
| |
| /* Zero-init our [out] parameter, */ |
| qdf_mem_set((uint8_t *) pMeasReqFrame, |
| sizeof(tpSirMacMeasReqActionFrame), 0); |
| |
| /* delegate to the framesc-generated code, */ |
| status = dot11f_unpack_measurement_request(pMac, pFrame, |
| nFrame, &mr, false); |
| if (DOT11F_FAILED(status)) { |
| pe_err("Failed to parse a Measurement Request frame (0x%08x, %d bytes):", |
| status, nFrame); |
| QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, |
| pFrame, nFrame); |
| return QDF_STATUS_E_FAILURE; |
| } else if (DOT11F_WARNED(status)) { |
| pe_debug("There were warnings while unpacking a Measurement Request frame (0x%08x, %d bytes):", |
| status, nFrame); |
| } |
| /* & "transliterate" from a 'tDot11fMeasurementRequest' to a */ |
| /* 'tpSirMacMeasReqActionFrame'... */ |
| pMeasReqFrame->actionHeader.category = mr.Category.category; |
| pMeasReqFrame->actionHeader.actionID = mr.Action.action; |
| pMeasReqFrame->actionHeader.dialogToken = mr.DialogToken.token; |
| |
| if (0 == mr.num_MeasurementRequest) { |
| pe_err("Missing mandatory IE in Measurement Request Frame"); |
| return QDF_STATUS_E_FAILURE; |
| } else if (1 < mr.num_MeasurementRequest) { |
| pe_warn( |
| FL("Warning: dropping extra Measurement Request IEs!")); |
| } |
| |
| pMeasReqFrame->measReqIE.type = DOT11F_EID_MEASUREMENTREQUEST; |
| pMeasReqFrame->measReqIE.length = DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN; |
| pMeasReqFrame->measReqIE.measToken = |
| mr.MeasurementRequest[0].measurement_token; |
| pMeasReqFrame->measReqIE.measReqMode = |
| (mr.MeasurementRequest[0].reserved << 3) | (mr. |
| MeasurementRequest[0]. |
| enable << 2) | (mr. |
| MeasurementRequest |
| [0]. |
| request |
| << 1) | |
| (mr.MeasurementRequest[0].report /*<< 0 */); |
| pMeasReqFrame->measReqIE.measType = |
| mr.MeasurementRequest[0].measurement_type; |
| |
| pMeasReqFrame->measReqIE.measReqField.channelNumber = |
| mr.MeasurementRequest[0].channel_no; |
| |
| qdf_mem_copy(pMeasReqFrame->measReqIE.measReqField.measStartTime, |
| mr.MeasurementRequest[0].meas_start_time, 8); |
| |
| pMeasReqFrame->measReqIE.measReqField.measDuration = |
| mr.MeasurementRequest[0].meas_duration; |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End sir_convert_meas_req_frame2_struct. */ |
| #endif |
| |
| void populate_dot11f_tspec(tSirMacTspecIE *pOld, tDot11fIETSPEC *pDot11f) |
| { |
| pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType; |
| pDot11f->tsid = pOld->tsinfo.traffic.tsid; |
| pDot11f->direction = pOld->tsinfo.traffic.direction; |
| pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy; |
| pDot11f->aggregation = pOld->tsinfo.traffic.aggregation; |
| pDot11f->psb = pOld->tsinfo.traffic.psb; |
| pDot11f->user_priority = pOld->tsinfo.traffic.userPrio; |
| pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy; |
| pDot11f->schedule = pOld->tsinfo.schedule.schedule; |
| /* As defined in IEEE 802.11-2007, section 7.3.2.30 |
| * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed |
| */ |
| pDot11f->size = (pOld->nomMsduSz & 0x7fff); |
| pDot11f->fixed = (pOld->nomMsduSz & 0x8000) ? 1 : 0; |
| pDot11f->max_msdu_size = pOld->maxMsduSz; |
| pDot11f->min_service_int = pOld->minSvcInterval; |
| pDot11f->max_service_int = pOld->maxSvcInterval; |
| pDot11f->inactivity_int = pOld->inactInterval; |
| pDot11f->suspension_int = pOld->suspendInterval; |
| pDot11f->service_start_time = pOld->svcStartTime; |
| pDot11f->min_data_rate = pOld->minDataRate; |
| pDot11f->mean_data_rate = pOld->meanDataRate; |
| pDot11f->peak_data_rate = pOld->peakDataRate; |
| pDot11f->burst_size = pOld->maxBurstSz; |
| pDot11f->delay_bound = pOld->delayBound; |
| pDot11f->min_phy_rate = pOld->minPhyRate; |
| pDot11f->surplus_bw_allowance = pOld->surplusBw; |
| pDot11f->medium_time = pOld->mediumTime; |
| |
| pDot11f->present = 1; |
| |
| } /* End populate_dot11f_tspec. */ |
| |
| void populate_dot11f_wmmtspec(tSirMacTspecIE *pOld, tDot11fIEWMMTSPEC *pDot11f) |
| { |
| pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType; |
| pDot11f->tsid = pOld->tsinfo.traffic.tsid; |
| pDot11f->direction = pOld->tsinfo.traffic.direction; |
| pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy; |
| pDot11f->aggregation = pOld->tsinfo.traffic.aggregation; |
| pDot11f->psb = pOld->tsinfo.traffic.psb; |
| pDot11f->user_priority = pOld->tsinfo.traffic.userPrio; |
| pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy; |
| pDot11f->burst_size_defn = pOld->tsinfo.traffic.burstSizeDefn; |
| /* As defined in IEEE 802.11-2007, section 7.3.2.30 |
| * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed |
| */ |
| pDot11f->size = (pOld->nomMsduSz & 0x7fff); |
| pDot11f->fixed = (pOld->nomMsduSz & 0x8000) ? 1 : 0; |
| pDot11f->max_msdu_size = pOld->maxMsduSz; |
| pDot11f->min_service_int = pOld->minSvcInterval; |
| pDot11f->max_service_int = pOld->maxSvcInterval; |
| pDot11f->inactivity_int = pOld->inactInterval; |
| pDot11f->suspension_int = pOld->suspendInterval; |
| pDot11f->service_start_time = pOld->svcStartTime; |
| pDot11f->min_data_rate = pOld->minDataRate; |
| pDot11f->mean_data_rate = pOld->meanDataRate; |
| pDot11f->peak_data_rate = pOld->peakDataRate; |
| pDot11f->burst_size = pOld->maxBurstSz; |
| pDot11f->delay_bound = pOld->delayBound; |
| pDot11f->min_phy_rate = pOld->minPhyRate; |
| pDot11f->surplus_bw_allowance = pOld->surplusBw; |
| pDot11f->medium_time = pOld->mediumTime; |
| |
| pDot11f->version = 1; |
| pDot11f->present = 1; |
| |
| } /* End populate_dot11f_wmmtspec. */ |
| |
| #if defined(FEATURE_WLAN_ESE) |
| /* Fill the ESE version currently supported */ |
| void populate_dot11f_ese_version(tDot11fIEESEVersion *pESEVersion) |
| { |
| pESEVersion->present = 1; |
| pESEVersion->version = ESE_VERSION_SUPPORTED; |
| } |
| |
| /* Fill the ESE ie for the station. */ |
| /* The State is Normal (1) */ |
| /* The MBSSID for station is set to 0. */ |
| void populate_dot11f_ese_rad_mgmt_cap(tDot11fIEESERadMgmtCap *pESERadMgmtCap) |
| { |
| pESERadMgmtCap->present = 1; |
| pESERadMgmtCap->mgmt_state = RM_STATE_NORMAL; |
| pESERadMgmtCap->mbssid_mask = 0; |
| pESERadMgmtCap->reserved = 0; |
| } |
| |
| QDF_STATUS populate_dot11f_ese_cckm_opaque(tpAniSirGlobal pMac, |
| tpSirCCKMie pCCKMie, |
| tDot11fIEESECckmOpaque *pDot11f) |
| { |
| int idx; |
| |
| if (pCCKMie->length) { |
| idx = find_ie_location(pMac, (tpSirRSNie) pCCKMie, |
| DOT11F_EID_ESECCKMOPAQUE); |
| if (0 <= idx) { |
| pDot11f->present = 1; |
| /* Dont include OUI */ |
| pDot11f->num_data = pCCKMie->cckmIEdata[idx + 1] - 4; |
| qdf_mem_copy(pDot11f->data, pCCKMie->cckmIEdata + idx + 2 + 4, /* EID,len,OUI */ |
| pCCKMie->cckmIEdata[idx + 1] - 4); /* Skip OUI */ |
| } |
| } |
| return QDF_STATUS_SUCCESS; |
| } /* End populate_dot11f_ese_cckm_opaque. */ |
| |
| void populate_dot11_tsrsie(tpAniSirGlobal pMac, |
| tSirMacESETSRSIE *pOld, |
| tDot11fIEESETrafStrmRateSet *pDot11f, |
| uint8_t rate_length) |
| { |
| pDot11f->tsid = pOld->tsid; |
| qdf_mem_copy(pDot11f->tsrates, pOld->rates, rate_length); |
| pDot11f->num_tsrates = rate_length; |
| pDot11f->present = 1; |
| } |
| #endif |
| |
| QDF_STATUS |
| populate_dot11f_tclas(tpAniSirGlobal pMac, |
| tSirTclasInfo *pOld, tDot11fIETCLAS *pDot11f) |
| { |
| pDot11f->user_priority = pOld->tclas.userPrio; |
| pDot11f->classifier_type = pOld->tclas.classifierType; |
| pDot11f->classifier_mask = pOld->tclas.classifierMask; |
| |
| switch (pDot11f->classifier_type) { |
| case SIR_MAC_TCLASTYPE_ETHERNET: |
| qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.source, |
| (uint8_t *) &pOld->tclasParams.eth.srcAddr, 6); |
| qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.dest, |
| (uint8_t *) &pOld->tclasParams.eth.dstAddr, 6); |
| pDot11f->info.EthParams.type = pOld->tclasParams.eth.type; |
| break; |
| case SIR_MAC_TCLASTYPE_TCPUDPIP: |
| pDot11f->info.IpParams.version = pOld->version; |
| if (SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version) { |
| qdf_mem_copy(pDot11f->info.IpParams.params.IpV4Params. |
| source, pOld->tclasParams.ipv4.srcIpAddr, |
| 4); |
| qdf_mem_copy(pDot11f->info.IpParams.params.IpV4Params. |
| dest, pOld->tclasParams.ipv4.dstIpAddr, 4); |
| pDot11f->info.IpParams.params.IpV4Params.src_port = |
| pOld->tclasParams.ipv4.srcPort; |
| pDot11f->info.IpParams.params.IpV4Params.dest_port = |
| pOld->tclasParams.ipv4.dstPort; |
| pDot11f->info.IpParams.params.IpV4Params.DSCP = |
| pOld->tclasParams.ipv4.dscp; |
| pDot11f->info.IpParams.params.IpV4Params.proto = |
| pOld->tclasParams.ipv4.protocol; |
| pDot11f->info.IpParams.params.IpV4Params.reserved = |
| pOld->tclasParams.ipv4.rsvd; |
| } else { |
| qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams. |
| params.IpV6Params.source, |
| (uint8_t *) pOld->tclasParams.ipv6. |
| srcIpAddr, 16); |
| qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams. |
| params.IpV6Params.dest, |
| (uint8_t *) pOld->tclasParams.ipv6. |
| dstIpAddr, 16); |
| pDot11f->info.IpParams.params.IpV6Params.src_port = |
| pOld->tclasParams.ipv6.srcPort; |
| pDot11f->info.IpParams.params.IpV6Params.dest_port = |
| pOld->tclasParams.ipv6.dstPort; |
| qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams. |
| params.IpV6Params.flow_label, |
| (uint8_t *) pOld->tclasParams.ipv6. |
| flowLabel, 3); |
| } |
| break; |
| case SIR_MAC_TCLASTYPE_8021DQ: |
| pDot11f->info.Params8021dq.tag_type = |
| pOld->tclasParams.t8021dq.tag; |
| break; |
| default: |
| pe_err("Bad TCLAS type %d in populate_dot11f_tclas", |
| pDot11f->classifier_type); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pDot11f->present = 1; |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_tclas. */ |
| |
| QDF_STATUS |
| populate_dot11f_wmmtclas(tpAniSirGlobal pMac, |
| tSirTclasInfo *pOld, tDot11fIEWMMTCLAS *pDot11f) |
| { |
| pDot11f->version = 1; |
| pDot11f->user_priority = pOld->tclas.userPrio; |
| pDot11f->classifier_type = pOld->tclas.classifierType; |
| pDot11f->classifier_mask = pOld->tclas.classifierMask; |
| |
| switch (pDot11f->classifier_type) { |
| case SIR_MAC_TCLASTYPE_ETHERNET: |
| qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.source, |
| (uint8_t *) &pOld->tclasParams.eth.srcAddr, 6); |
| qdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.dest, |
| (uint8_t *) &pOld->tclasParams.eth.dstAddr, 6); |
| pDot11f->info.EthParams.type = pOld->tclasParams.eth.type; |
| break; |
| case SIR_MAC_TCLASTYPE_TCPUDPIP: |
| pDot11f->info.IpParams.version = pOld->version; |
| if (SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version) { |
| qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams. |
| params.IpV4Params.source, |
| (uint8_t *) pOld->tclasParams.ipv4. |
| srcIpAddr, 4); |
| qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams. |
| params.IpV4Params.dest, |
| (uint8_t *) pOld->tclasParams.ipv4. |
| dstIpAddr, 4); |
| pDot11f->info.IpParams.params.IpV4Params.src_port = |
| pOld->tclasParams.ipv4.srcPort; |
| pDot11f->info.IpParams.params.IpV4Params.dest_port = |
| pOld->tclasParams.ipv4.dstPort; |
| pDot11f->info.IpParams.params.IpV4Params.DSCP = |
| pOld->tclasParams.ipv4.dscp; |
| pDot11f->info.IpParams.params.IpV4Params.proto = |
| pOld->tclasParams.ipv4.protocol; |
| pDot11f->info.IpParams.params.IpV4Params.reserved = |
| pOld->tclasParams.ipv4.rsvd; |
| } else { |
| qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams. |
| params.IpV6Params.source, |
| (uint8_t *) pOld->tclasParams.ipv6. |
| srcIpAddr, 16); |
| qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams. |
| params.IpV6Params.dest, |
| (uint8_t *) pOld->tclasParams.ipv6. |
| dstIpAddr, 16); |
| pDot11f->info.IpParams.params.IpV6Params.src_port = |
| pOld->tclasParams.ipv6.srcPort; |
| pDot11f->info.IpParams.params.IpV6Params.dest_port = |
| pOld->tclasParams.ipv6.dstPort; |
| qdf_mem_copy((uint8_t *) &pDot11f->info.IpParams. |
| params.IpV6Params.flow_label, |
| (uint8_t *) pOld->tclasParams.ipv6. |
| flowLabel, 3); |
| } |
| break; |
| case SIR_MAC_TCLASTYPE_8021DQ: |
| pDot11f->info.Params8021dq.tag_type = |
| pOld->tclasParams.t8021dq.tag; |
| break; |
| default: |
| pe_err("Bad TCLAS type %d in populate_dot11f_tclas", |
| pDot11f->classifier_type); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pDot11f->present = 1; |
| |
| return QDF_STATUS_SUCCESS; |
| |
| } /* End populate_dot11f_wmmtclas. */ |
| |
| QDF_STATUS populate_dot11f_wsc(tpAniSirGlobal pMac, |
| tDot11fIEWscBeacon *pDot11f) |
| { |
| |
| uint32_t wpsState; |
| |
| pDot11f->Version.present = 1; |
| pDot11f->Version.major = 0x01; |
| pDot11f->Version.minor = 0x00; |
| |
| if (wlan_cfg_get_int(pMac, (uint16_t) WNI_CFG_WPS_STATE, &wpsState) != |
| QDF_STATUS_SUCCESS) |
| pe_err("Failed to cfg get id %d", WNI_CFG_WPS_STATE); |
| |
| pDot11f->WPSState.present = 1; |
| pDot11f->WPSState.state = (uint8_t) wpsState; |
| |
| pDot11f->APSetupLocked.present = 0; |
| |
| pDot11f->SelectedRegistrar.present = 0; |
| |
| pDot11f->DevicePasswordID.present = 0; |
| |
| pDot11f->SelectedRegistrarConfigMethods.present = 0; |
| |
| pDot11f->UUID_E.present = 0; |
| |
| pDot11f->RFBands.present = 0; |
| |
| pDot11f->present = 1; |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac, |
| tDot11fIEWscBeacon *pDot11f) |
| { |
| const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo); |
| uint32_t devicepasswdId; |
| |
| pDot11f->APSetupLocked.present = 1; |
| pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked; |
| |
| pDot11f->SelectedRegistrar.present = 1; |
| pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar; |
| |
| if (wlan_cfg_get_int |
| (pMac, (uint16_t) WNI_CFG_WPS_DEVICE_PASSWORD_ID, |
| &devicepasswdId) != QDF_STATUS_SUCCESS) |
| pe_err("Failed to cfg get id %d", |
| WNI_CFG_WPS_DEVICE_PASSWORD_ID); |
| |
| pDot11f->DevicePasswordID.present = 1; |
| pDot11f->DevicePasswordID.id = (uint16_t) devicepasswdId; |
| |
| pDot11f->SelectedRegistrarConfigMethods.present = 1; |
| pDot11f->SelectedRegistrarConfigMethods.methods = |
| pWscIeInfo->selectedRegistrarConfigMethods; |
| |
| /* UUID_E and RF Bands are applicable only for dual band AP */ |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS de_populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac, |
| tDot11fIEWscBeacon *pDot11f) |
| { |
| pDot11f->APSetupLocked.present = 0; |
| pDot11f->SelectedRegistrar.present = 0; |
| pDot11f->DevicePasswordID.present = 0; |
| pDot11f->SelectedRegistrarConfigMethods.present = 0; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS populate_dot11f_probe_res_wpsi_es(tpAniSirGlobal pMac, |
| tDot11fIEWscProbeRes *pDot11f, |
| tpPESession psessionEntry) |
| { |
| |
| tSirWPSProbeRspIE *pSirWPSProbeRspIE; |
| |
| pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE; |
| |
| if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) { |
| pDot11f->present = 1; |
| pDot11f->Version.present = 1; |
| pDot11f->Version.major = |
| (uint8_t) ((pSirWPSProbeRspIE->Version & 0xF0) >> 4); |
| pDot11f->Version.minor = |
| (uint8_t) (pSirWPSProbeRspIE->Version & 0x0F); |
| } else { |
| pDot11f->present = 0; |
| pDot11f->Version.present = 0; |
| } |
| |
| if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_STATE_PRESENT) { |
| |
| pDot11f->WPSState.present = 1; |
| pDot11f->WPSState.state = (uint8_t) pSirWPSProbeRspIE->wpsState; |
| } else |
| pDot11f->WPSState.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT) { |
| pDot11f->APSetupLocked.present = 1; |
| pDot11f->APSetupLocked.fLocked = |
| pSirWPSProbeRspIE->APSetupLocked; |
| } else |
| pDot11f->APSetupLocked.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) { |
| pDot11f->SelectedRegistrar.present = 1; |
| pDot11f->SelectedRegistrar.selected = |
| pSirWPSProbeRspIE->SelectedRegistra; |
| } else |
| pDot11f->SelectedRegistrar.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT) { |
| pDot11f->DevicePasswordID.present = 1; |
| pDot11f->DevicePasswordID.id = |
| pSirWPSProbeRspIE->DevicePasswordID; |
| } else |
| pDot11f->DevicePasswordID.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT) { |
| pDot11f->SelectedRegistrarConfigMethods.present = 1; |
| pDot11f->SelectedRegistrarConfigMethods.methods = |
| pSirWPSProbeRspIE->SelectedRegistraCfgMethod; |
| } else |
| pDot11f->SelectedRegistrarConfigMethods.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) { |
| pDot11f->ResponseType.present = 1; |
| pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType; |
| } else |
| pDot11f->ResponseType.present = 0; |
| |
| if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_UUIDE_PRESENT) { |
| pDot11f->UUID_E.present = 1; |
| qdf_mem_copy(pDot11f->UUID_E.uuid, pSirWPSProbeRspIE->UUID_E, |
| WNI_CFG_WPS_UUID_LEN); |
| } else |
| pDot11f->UUID_E.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_MANUFACTURE_PRESENT) { |
| pDot11f->Manufacturer.present = 1; |
| pDot11f->Manufacturer.num_name = |
| pSirWPSProbeRspIE->Manufacture.num_name; |
| qdf_mem_copy(pDot11f->Manufacturer.name, |
| pSirWPSProbeRspIE->Manufacture.name, |
| pSirWPSProbeRspIE->Manufacture.num_name); |
| } else |
| pDot11f->Manufacturer.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) { |
| pDot11f->ModelName.present = 1; |
| pDot11f->ModelName.num_text = |
| pSirWPSProbeRspIE->ModelName.num_text; |
| qdf_mem_copy(pDot11f->ModelName.text, |
| pSirWPSProbeRspIE->ModelName.text, |
| pDot11f->ModelName.num_text); |
| } else |
| pDot11f->ModelName.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) { |
| pDot11f->ModelNumber.present = 1; |
| pDot11f->ModelNumber.num_text = |
| pSirWPSProbeRspIE->ModelNumber.num_text; |
| qdf_mem_copy(pDot11f->ModelNumber.text, |
| pSirWPSProbeRspIE->ModelNumber.text, |
| pDot11f->ModelNumber.num_text); |
| } else |
| pDot11f->ModelNumber.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT) { |
| pDot11f->SerialNumber.present = 1; |
| pDot11f->SerialNumber.num_text = |
| pSirWPSProbeRspIE->SerialNumber.num_text; |
| qdf_mem_copy(pDot11f->SerialNumber.text, |
| pSirWPSProbeRspIE->SerialNumber.text, |
| pDot11f->SerialNumber.num_text); |
| } else |
| pDot11f->SerialNumber.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT) { |
| pDot11f->PrimaryDeviceType.present = 1; |
| qdf_mem_copy(pDot11f->PrimaryDeviceType.oui, |
| pSirWPSProbeRspIE->PrimaryDeviceOUI, |
| sizeof(pSirWPSProbeRspIE->PrimaryDeviceOUI)); |
| pDot11f->PrimaryDeviceType.primary_category = |
| (uint16_t) pSirWPSProbeRspIE->PrimaryDeviceCategory; |
| pDot11f->PrimaryDeviceType.sub_category = |
| (uint16_t) pSirWPSProbeRspIE->DeviceSubCategory; |
| } else |
| pDot11f->PrimaryDeviceType.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_DEVICENAME_PRESENT) { |
| pDot11f->DeviceName.present = 1; |
| pDot11f->DeviceName.num_text = |
| pSirWPSProbeRspIE->DeviceName.num_text; |
| qdf_mem_copy(pDot11f->DeviceName.text, |
| pSirWPSProbeRspIE->DeviceName.text, |
| pDot11f->DeviceName.num_text); |
| } else |
| pDot11f->DeviceName.present = 0; |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT) { |
| pDot11f->ConfigMethods.present = 1; |
| pDot11f->ConfigMethods.methods = |
| pSirWPSProbeRspIE->ConfigMethod; |
| } else |
| pDot11f->ConfigMethods.present = 0; |
| |
| if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RF_BANDS_PRESENT) { |
| pDot11f->RFBands.present = 1; |
| pDot11f->RFBands.bands = pSirWPSProbeRspIE->RFBand; |
| } else |
| pDot11f->RFBands.present = 0; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS populate_dot11f_assoc_res_wpsi_es(tpAniSirGlobal pMac, |
| tDot11fIEWscAssocRes *pDot11f, |
| tpPESession psessionEntry) |
| { |
| tSirWPSProbeRspIE *pSirWPSProbeRspIE; |
| |
| pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE; |
| |
| if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) { |
| pDot11f->present = 1; |
| pDot11f->Version.present = 1; |
| pDot11f->Version.major = |
| (uint8_t) ((pSirWPSProbeRspIE->Version & 0xF0) >> 4); |
| pDot11f->Version.minor = |
| (uint8_t) (pSirWPSProbeRspIE->Version & 0x0F); |
| } else { |
| pDot11f->present = 0; |
| pDot11f->Version.present = 0; |
| } |
| |
| if (pSirWPSProbeRspIE-> |
| FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) { |
| pDot11f->ResponseType.present = 1; |
| pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType; |
| } else |
| pDot11f->ResponseType.present = 0; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS populate_dot11f_beacon_wpsi_es(tpAniSirGlobal pMac, |
| tDot11fIEWscBeacon *pDot11f, |
| tpPESession psessionEntry) |
| { |
| |
| tSirWPSBeaconIE *pSirWPSBeaconIE; |
| |
| pSirWPSBeaconIE = &psessionEntry->APWPSIEs.SirWPSBeaconIE; |
| |
| if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) { |
| pDot11f->present = 1; |
| pDot11f->Version.present = 1; |
| pDot11f->Version.major = |
| (uint8_t) ((pSirWPSBeaconIE->Version & 0xF0) >> 4); |
| pDot11f->Version.minor = |
| (uint8_t) (pSirWPSBeaconIE->Version & 0x0F); |
| } else { |
| pDot11f->present = 0; |
| pDot11f->Version.present = 0; |
| } |
| |
| if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_STATE_PRESENT) { |
| |
| pDot11f->WPSState.present = 1; |
| pDot11f->WPSState.state = (uint8_t) pSirWPSBeaconIE->wpsState; |
| } else |
| pDot11f->WPSState.present = 0; |
| |
| if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_APSETUPLOCK_PRESENT) { |
| pDot11f->APSetupLocked.present = 1; |
| pDot11f->APSetupLocked.fLocked = pSirWPSBeaconIE->APSetupLocked; |
| } else |
| pDot11f->APSetupLocked.present = 0; |
| |
| if (pSirWPSBeaconIE-> |
| FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT) { |
| pDot11f->SelectedRegistrar.present = 1; |
| pDot11f->SelectedRegistrar.selected = |
| pSirWPSBeaconIE->SelectedRegistra; |
| } else |
| pDot11f->SelectedRegistrar.present = 0; |
| |
| if (pSirWPSBeaconIE-> |
| FieldPresent & SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT) { |
| pDot11f->DevicePasswordID.present = 1; |
| pDot11f->DevicePasswordID.id = |
| pSirWPSBeaconIE->DevicePasswordID; |
| } else |
| pDot11f->DevicePasswordID.present = 0; |
| |
| if (pSirWPSBeaconIE-> |
| FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT) { |
| pDot11f->SelectedRegistrarConfigMethods.present = 1; |
| pDot11f->SelectedRegistrarConfigMethods.methods = |
| pSirWPSBeaconIE->SelectedRegistraCfgMethod; |
| } else |
| pDot11f->SelectedRegistrarConfigMethods.present = 0; |
| |
| if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_UUIDE_PRESENT) { |
| pDot11f->UUID_E.present = 1; |
| qdf_mem_copy(pDot11f->UUID_E.uuid, pSirWPSBeaconIE->UUID_E, |
| WNI_CFG_WPS_UUID_LEN); |
| } else |
| pDot11f->UUID_E.present = 0; |
| |
| if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_RF_BANDS_PRESENT) { |
| pDot11f->RFBands.present = 1; |
| pDot11f->RFBands.bands = pSirWPSBeaconIE->RFBand; |
| } else |
| pDot11f->RFBands.present = 0; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS populate_dot11f_wsc_in_probe_res(tpAniSirGlobal pMac, |
| tDot11fIEWscProbeRes *pDot11f) |
| { |
| uint32_t cfgMethods; |
| uint32_t cfgStrLen; |
| uint32_t val; |
| uint32_t wpsVersion, wpsState; |
| |
| if (wlan_cfg_get_int(pMac, (uint16_t) WNI_CFG_WPS_VERSION, &wpsVersion) != |
| QDF_STATUS_SUCCESS) |
| pe_err("Failed to cfg get id %d", WNI_CFG_WPS_VERSION); |
| |
| pDot11f->Version.present = 1; |
| pDot11f->Version.major = (uint8_t) ((wpsVersion & 0xF0) >> 4); |
| pDot11f->Version.minor = (uint8_t) (wpsVersion & 0x0F); |
| |
| if (wlan_cfg_get_int(pMac, (uint16_t) WNI_CFG_WPS_STATE, &wpsState) != |
| QDF_STATUS_SUCCESS) |
| pe_err("Failed to cfg get id %d", WNI_CFG_WPS_STATE); |
| |
| pDot11f->WPSState.present = 1; |
| pDot11f->WPSState.state = (uint8_t) wpsState; |
| |
| pDot11f->APSetupLocked.present = 0; |
| |
| pDot11f->SelectedRegistrar.present = 0; |
| |
| pDot11f->DevicePasswordID.present = 0; |
| |
| pDot11f->SelectedRegistrarConfigMethods.present = 0; |
| |
| pDot11f->ResponseType.present = 1; |
| if ((pMac->lim.wscIeInfo.reqType == REQ_TYPE_REGISTRAR) || |
| (pMac->lim.wscIeInfo.reqType == REQ_TYPE_WLAN_MANAGER_REGISTRAR)) { |
| pDot11f->ResponseType.resType = RESP_TYPE_ENROLLEE_OPEN_8021X; |
| } else { |
| pDot11f->ResponseType.resType = RESP_TYPE_AP; |
| } |
| |
| /* UUID is a 16 byte long binary. Still use wlan_cfg_get_str to get it. */ |
| pDot11f->UUID_E.present = 1; |
| cfgStrLen = WNI_CFG_WPS_UUID_LEN; |
| if (wlan_cfg_get_str(pMac, |
| WNI_CFG_WPS_UUID, |
| pDot11f->UUID_E.uuid, &cfgStrLen) != QDF_STATUS_SUCCESS) { |
| *(pDot11f->UUID_E.uuid) = '\0'; |
| } |
| |
| pDot11f->Manufacturer.present = 1; |
| cfgStrLen = WNI_CFG_MANUFACTURER_NAME_LEN; |
| if (wlan_cfg_get_str(pMac, |
| WNI_CFG_MANUFACTURER_NAME, |
| pDot11f->Manufacturer.name, |
| &cfgStrLen) != QDF_STATUS_SUCCESS) { |
| pDot11f->Manufacturer.num_name = 0; |
| } else { |
| pDot11f->Manufacturer.num_name = |
| (uint8_t) (cfgStrLen & 0x000000FF); |
| } |
| |
| pDot11f->ModelName.present = 1; |
| cfgStrLen = WNI_CFG_MODEL_NAME_LEN; |
| if (wlan_cfg_get_str(pMac, |
| WNI_CFG_MODEL_NAME, |
| pDot11f->ModelName.text, |
| &cfgStrLen) != QDF_STATUS_SUCCESS) { |
| pDot11f->ModelName.num_text = 0; |
| } else { |
| pDot11f->ModelName.num_text = |
| (uint8_t) (cfgStrLen & 0x000000FF); |
| } |
| |
| pDot11f->ModelNumber.present = 1; |
| cfgStrLen = WNI_CFG_MODEL_NUMBER_LEN; |
| if (wlan_cfg_get_str(pMac, |
| WNI_CFG_MODEL_NUMBER, |
| pDot11f->ModelNumber.text, |
| &cfgStrLen) != QDF_STATUS_SUCCESS) { |
| pDot11f->ModelNumber.num_text = 0; |
| } else { |
| pDot11f->ModelNumber.num_text = |
| (uint8_t) (cfgStrLen & 0x000000FF); |
| } |
| |
| pDot11f->SerialNumber.present = 1; |
| cfgStrLen = WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN; |
| if (wlan_cfg_get_str(pMac, |
| WNI_CFG_MANUFACTURER_PRODUCT_VERSION, |
| pDot11f->SerialNumber.text, |
| &cfgStrLen) != QDF_STATUS_SUCCESS) { |
| pDot11f->SerialNumber.num_text = 0; |
| } else { |
| pDot11f->SerialNumber.num_text = |
| (uint8_t) (cfgStrLen & 0x000000FF); |
| } |
| |
| pDot11f->PrimaryDeviceType.present = 1; |
| |
| if (wlan_cfg_get_int(pMac, WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY, &val) != |
| QDF_STATUS_SUCCESS) { |
| pe_err("cfg get prim device category failed"); |
| } else |
| pDot11f->PrimaryDeviceType.primary_category = (uint16_t) val; |
| |
| if (wlan_cfg_get_int(pMac, WNI_CFG_WPS_PIMARY_DEVICE_OUI, &val) != |
| QDF_STATUS_SUCCESS) { |
| pe_err("cfg get prim device OUI failed"); |
| } else { |
| *(pDot11f->PrimaryDeviceType.oui) = |
| (uint8_t) ((val >> 24) & 0xff); |
| *(pDot11f->PrimaryDeviceType.oui + 1) = |
| (uint8_t) ((val >> 16) & 0xff); |
| *(pDot11f->PrimaryDeviceType.oui + 2) = |
| (uint8_t) ((val >> 8) & 0xff); |
| *(pDot11f->PrimaryDeviceType.oui + 3) = |
| (uint8_t) ((val & 0xff)); |
| } |
| |
| if (wlan_cfg_get_int(pMac, WNI_CFG_WPS_DEVICE_SUB_CATEGORY, &val) != |
| QDF_STATUS_SUCCESS) { |
| pe_err("cfg get prim device sub category failed"); |
| } else |
| pDot11f->PrimaryDeviceType.sub_category = (uint16_t) val; |
| |
| pDot11f->DeviceName.present = 1; |
| cfgStrLen = WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN; |
| if (wlan_cfg_get_str(pMac, |
| WNI_CFG_MANUFACTURER_PRODUCT_NAME, |
| pDot11f->DeviceName.text, |
| &cfgStrLen) != QDF_STATUS_SUCCESS) { |
| pDot11f->DeviceName.num_text = 0; |
| } else { |
| pDot11f->DeviceName.num_text = |
| (uint8_t) (cfgStrLen & 0x000000FF); |
| } |
| |
| if (wlan_cfg_get_int(pMac, |
| WNI_CFG_WPS_CFG_METHOD, |
| &cfgMethods) != QDF_STATUS_SUCCESS) { |
| pDot11f->ConfigMethods.present = 0; |
| pDot11f->ConfigMethods.methods = 0; |
| } else { |
| pDot11f->ConfigMethods.present = 1; |
| pDot11f->ConfigMethods.methods = |
| (uint16_t) (cfgMethods & 0x0000FFFF); |
| } |
| |
| pDot11f->RFBands.present = 0; |
| |
| pDot11f->present = 1; |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS |
| populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac, |
| tDot11fIEWscProbeRes *pDot11f) |
| { |
| const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo); |
| uint32_t devicepasswdId; |
| |
| pDot11f->APSetupLocked.present = 1; |
| pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked; |
| |
| pDot11f->SelectedRegistrar.present = 1; |
| pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar; |
| |
| if (wlan_cfg_get_int |
| (pMac, (uint16_t) WNI_CFG_WPS_DEVICE_PASSWORD_ID, |
| &devicepasswdId) != QDF_STATUS_SUCCESS) |
| pe_err("Failed to cfg get id %d", |
| WNI_CFG_WPS_DEVICE_PASSWORD_ID); |
| |
| pDot11f->DevicePasswordID.present = 1; |
| pDot11f->DevicePasswordID.id = (uint16_t) devicepasswdId; |
| |
| pDot11f->SelectedRegistrarConfigMethods.present = 1; |
| pDot11f->SelectedRegistrarConfigMethods.methods = |
| pWscIeInfo->selectedRegistrarConfigMethods; |
| |
| /* UUID_E and RF Bands are applicable only for dual band AP */ |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS |
| de_populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac, |
| tDot11fIEWscProbeRes * |
| pDot11f) |
| { |
| pDot11f->APSetupLocked.present = 0; |
| pDot11f->SelectedRegistrar.present = 0; |
| pDot11f->DevicePasswordID.present = 0; |
| pDot11f->SelectedRegistrarConfigMethods.present = 0; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS populate_dot11f_assoc_res_wsc_ie(tpAniSirGlobal pMac, |
| tDot11fIEWscAssocRes *pDot11f, |
| tpSirAssocReq pRcvdAssocReq) |
| { |
| uint32_t ret; |
| const uint8_t *wscIe; |
| tDot11fIEWscAssocReq parsedWscAssocReq = { 0, }; |
| |
| wscIe = limGetWscIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata, |
| pRcvdAssocReq->addIE.length); |
| if (wscIe != NULL) { |
| /* retrieve WSC IE from given AssocReq */ |
| ret = dot11f_unpack_ie_wsc_assoc_req(pMac, |
| /* EID, length, OUI */ |
| (uint8_t *)wscIe + 2 + 4, |
| /* length without OUI */ |
| wscIe[1] - 4, |
| &parsedWscAssocReq, false); |
| if (!DOT11F_SUCCEEDED(ret)) { |
| pe_err("unpack failed, ret: %d", ret); |
| return QDF_STATUS_E_INVAL; |
| } |
| |
| pDot11f->present = 1; |
| /* version has to be 0x10 */ |
| pDot11f->Version.present = 1; |
| pDot11f->Version.major = 0x1; |
| pDot11f->Version.minor = 0x0; |
| |
| pDot11f->ResponseType.present = 1; |
| |
| if ((parsedWscAssocReq.RequestType.reqType == |
| REQ_TYPE_REGISTRAR) |
| || (parsedWscAssocReq.RequestType.reqType == |
| REQ_TYPE_WLAN_MANAGER_REGISTRAR)) { |
| pDot11f->ResponseType.resType = |
| RESP_TYPE_ENROLLEE_OPEN_8021X; |
| } else { |
| pDot11f->ResponseType.resType = RESP_TYPE_AP; |
| } |
| /* Version infomration should be taken from our capability as well as peers */ |
| /* TODO: currently it takes from peers only */ |
| if (parsedWscAssocReq.VendorExtension.present && |
| parsedWscAssocReq.VendorExtension.Version2.present) { |
| pDot11f->VendorExtension.present = 1; |
| pDot11f->VendorExtension.vendorId[0] = 0x00; |
| pDot11f->VendorExtension.vendorId[1] = 0x37; |
| pDot11f->VendorExtension.vendorId[2] = 0x2A; |
| pDot11f->VendorExtension.Version2.present = 1; |
| pDot11f->VendorExtension.Version2.major = |
| parsedWscAssocReq.VendorExtension.Version2.major; |
| pDot11f->VendorExtension.Version2.minor = |
| parsedWscAssocReq.VendorExtension.Version2.minor; |
| } |
| } |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS populate_dot11_assoc_res_p2p_ie(tpAniSirGlobal pMac, |
| tDot11fIEP2PAssocRes *pDot11f, |
| tpSirAssocReq pRcvdAssocReq) |
| { |
| const uint8_t *p2pIe; |
| |
| p2pIe = limGetP2pIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata, |
| pRcvdAssocReq->addIE.length); |
| if (p2pIe != NULL) { |
| pDot11f->present = 1; |
| pDot11f->P2PStatus.present = 1; |
| pDot11f->P2PStatus.status = QDF_STATUS_SUCCESS; |
| pDot11f->ExtendedListenTiming.present = 0; |
| } |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| |
| QDF_STATUS populate_dot11f_wfatpc(tpAniSirGlobal pMac, |
| tDot11fIEWFATPC *pDot11f, uint8_t txPower, |
| uint8_t linkMargin) |
| { |
| pDot11f->txPower = txPower; |
| pDot11f->linkMargin = linkMargin; |
| pDot11f->present = 1; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS |
| populate_dot11f_beacon_report(tpAniSirGlobal pMac, |
| tDot11fIEMeasurementReport *pDot11f, |
| tSirMacBeaconReport *pBeaconReport, |
| struct rrm_beacon_report_last_beacon_params |
| *last_beacon_report_params) |
| { |
| |
| pDot11f->report.Beacon.regClass = pBeaconReport->regClass; |
| pDot11f->report.Beacon.channel = pBeaconReport->channel; |
| qdf_mem_copy(pDot11f->report.Beacon.meas_start_time, |
| pBeaconReport->measStartTime, |
| sizeof(pDot11f->report.Beacon.meas_start_time)); |
| pDot11f->report.Beacon.meas_duration = pBeaconReport->measDuration; |
| pDot11f->report.Beacon.condensed_PHY = pBeaconReport->phyType; |
| pDot11f->report.Beacon.reported_frame_type = |
| !pBeaconReport->bcnProbeRsp; |
| pDot11f->report.Beacon.RCPI = pBeaconReport->rcpi; |
| pDot11f->report.Beacon.RSNI = pBeaconReport->rsni; |
| qdf_mem_copy(pDot11f->report.Beacon.BSSID, pBeaconReport->bssid, |
| sizeof(tSirMacAddr)); |
| pDot11f->report.Beacon.antenna_id = pBeaconReport->antennaId; |
| pDot11f->report.Beacon.parent_TSF = pBeaconReport->parentTSF; |
| |
| if (pBeaconReport->numIes) { |
| pDot11f->report.Beacon.BeaconReportFrmBody.present = 1; |
| qdf_mem_copy(pDot11f->report.Beacon.BeaconReportFrmBody. |
| reportedFields, pBeaconReport->Ies, |
| pBeaconReport->numIes); |
| pDot11f->report.Beacon.BeaconReportFrmBody.num_reportedFields = |
| pBeaconReport->numIes; |
| } |
| |
| if (last_beacon_report_params && |
| last_beacon_report_params->last_beacon_ind) { |
| pe_debug("Including Last Beacon Report in RRM Frame, report_id %d, frag_id %d", |
| last_beacon_report_params->report_id, |
| last_beacon_report_params->frag_id); |
| pDot11f->report.Beacon.beacon_report_frm_body_fragment_id. |
| present = 1; |
| pDot11f->report.Beacon.beacon_report_frm_body_fragment_id. |
| beacon_report_id = last_beacon_report_params->report_id; |
| pDot11f->report.Beacon.beacon_report_frm_body_fragment_id. |
| fragment_id_number = last_beacon_report_params->frag_id; |
| |
| pDot11f->report.Beacon.last_beacon_report_indication.present = 1; |
| |
| if (last_beacon_report_params->frag_id == |
| (last_beacon_report_params->num_frags - 1)) { |
| pDot11f->report.Beacon. |
| beacon_report_frm_body_fragment_id. |
| more_fragments = 0; |
| pDot11f->report.Beacon.last_beacon_report_indication. |
| last_fragment = 1; |
| pe_debug("Last Fragment"); |
| } else { |
| pDot11f->report.Beacon. |
| beacon_report_frm_body_fragment_id. |
| more_fragments = 1; |
| pDot11f->report.Beacon.last_beacon_report_indication. |
| last_fragment = 0; |
| } |
| } |
| return QDF_STATUS_SUCCESS; |
| |
| } |
| |
| QDF_STATUS populate_dot11f_rrm_ie(tpAniSirGlobal pMac, |
| tDot11fIERRMEnabledCap *pDot11f, |
| tpPESession psessionEntry) |
| { |
| tpRRMCaps pRrmCaps; |
| uint8_t *bytes; |
| |
| pRrmCaps = rrm_get_capabilities(pMac, psessionEntry); |
| |
| pDot11f->LinkMeasurement = pRrmCaps->LinkMeasurement; |
| pDot11f->NeighborRpt = pRrmCaps->NeighborRpt; |
| pDot11f->parallel = pRrmCaps->parallel; |
| pDot11f->repeated = pRrmCaps->repeated; |
| pDot11f->BeaconPassive = pRrmCaps->BeaconPassive; |
| pDot11f->BeaconActive = pRrmCaps->BeaconActive; |
| pDot11f->BeaconTable = pRrmCaps->BeaconTable; |
| pDot11f->BeaconRepCond = pRrmCaps->BeaconRepCond; |
| pDot11f->FrameMeasurement = pRrmCaps->FrameMeasurement; |
| pDot11f->ChannelLoad = pRrmCaps->ChannelLoad; |
| pDot11f->NoiseHistogram = pRrmCaps->NoiseHistogram; |
| pDot11f->statistics = pRrmCaps->statistics; |
| pDot11f->LCIMeasurement = pRrmCaps->LCIMeasurement; |
| pDot11f->LCIAzimuth = pRrmCaps->LCIAzimuth; |
| pDot11f->TCMCapability = pRrmCaps->TCMCapability; |
| pDot11f->triggeredTCM = pRrmCaps->triggeredTCM; |
| pDot11f->APChanReport = pRrmCaps->APChanReport; |
| pDot11f->RRMMIBEnabled = pRrmCaps->RRMMIBEnabled; |
| pDot11f->operatingChanMax = pRrmCaps->operatingChanMax; |
| pDot11f->nonOperatinChanMax = pRrmCaps->nonOperatingChanMax; |
| pDot11f->MeasurementPilot = pRrmCaps->MeasurementPilot; |
| pDot11f->MeasurementPilotEnabled = pRrmCaps->MeasurementPilotEnabled; |
| pDot11f->NeighborTSFOffset = pRrmCaps->NeighborTSFOffset; |
| pDot11f->RCPIMeasurement = pRrmCaps->RCPIMeasurement; |
| pDot11f->RSNIMeasurement = pRrmCaps->RSNIMeasurement; |
| pDot11f->BssAvgAccessDelay = pRrmCaps->BssAvgAccessDelay; |
| pDot11f->BSSAvailAdmission = pRrmCaps->BSSAvailAdmission; |
| pDot11f->AntennaInformation = pRrmCaps->AntennaInformation; |
| pDot11f->fine_time_meas_rpt = pRrmCaps->fine_time_meas_rpt; |
| pDot11f->lci_capability = pRrmCaps->lci_capability; |
| pDot11f->reserved = pRrmCaps->reserved; |
| |
| bytes = (uint8_t *) pDot11f + 1; /* ignore present field */ |
| pe_debug("RRM Enabled Cap IE: %02x %02x %02x %02x %02x", |
| bytes[0], bytes[1], bytes[2], bytes[3], bytes[4]); |
| |
| pDot11f->present = 1; |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| void populate_mdie(tpAniSirGlobal pMac, |
| tDot11fIEMobilityDomain *pDot11f, |
| uint8_t mdie[SIR_MDIE_SIZE]) |
| { |
| pDot11f->present = 1; |
| pDot11f->MDID = (uint16_t) ((mdie[1] << 8) | (mdie[0])); |
| |
| /* Plugfest fix */ |
| pDot11f->overDSCap = (mdie[2] & 0x01); |
| pDot11f->resourceReqCap = ((mdie[2] >> 1) & 0x01); |
| |
| } |
| |
| void populate_ft_info(tpAniSirGlobal pMac, tDot11fIEFTInfo *pDot11f) |
| { |
| pDot11f->present = 1; |
| pDot11f->IECount = 0; /* TODO: put valid data during reassoc. */ |
| /* All other info is zero. */ |
| |
| } |
| |
| void populate_dot11f_assoc_rsp_rates(tpAniSirGlobal pMac, |
| tDot11fIESuppRates *pSupp, |
| tDot11fIEExtSuppRates *pExt, |
| uint16_t *_11bRates, uint16_t *_11aRates) |
| { |
| uint8_t num_supp = 0, num_ext = 0; |
| uint8_t i, j; |
| |
| for (i = 0; (i < SIR_NUM_11B_RATES && _11bRates[i]); i++, num_supp++) { |
| pSupp->rates[num_supp] = (uint8_t) _11bRates[i]; |
| } |
| for (j = 0; (j < SIR_NUM_11A_RATES && _11aRates[j]); j++) { |
| if (num_supp < 8) |
| pSupp->rates[num_supp++] = (uint8_t) _11aRates[j]; |
| else |
| pExt->rates[num_ext++] = (uint8_t) _11aRates[j]; |
| } |
| |
| if (num_supp) { |
| pSupp->num_rates = num_supp; |
| pSupp->present = 1; |
| } |
| if (num_ext) { |
| pExt->num_rates = num_ext; |
| pExt->present = 1; |
| } |
| } |
| |
| void populate_dot11f_timeout_interval(tpAniSirGlobal pMac, |
| tDot11fIETimeoutInterval *pDot11f, |
| uint8_t type, uint32_t value) |
| { |
| pDot11f->present = 1; |
| pDot11f->timeoutType = type; |
| pDot11f->timeoutValue = value; |
| } |
| |
| /** |
| * populate_dot11f_timing_advert_frame() - Populate the TA mgmt frame fields |
| * @pMac: the MAC context |
| * @frame: pointer to the TA frame |
| * |
| * Return: The SIR status. |
| */ |
| QDF_STATUS |
| populate_dot11f_timing_advert_frame(tpAniSirGlobal mac_ctx, |
| tDot11fTimingAdvertisementFrame *frame) |
| { |
| uint32_t val, len; |
| uint16_t item; |
| uint8_t temp[CFG_MAX_STR_LEN], code[3]; |
| QDF_STATUS nSirStatus; |
| |
| /* Capabilities */ |
| wlan_cfg_get_int(mac_ctx, WNI_CFG_PRIVACY_ENABLED, &val); |
| if (val) |
| frame->Capabilities.privacy = 1; |
| |
| wlan_cfg_get_int(mac_ctx, WNI_CFG_SHORT_PREAMBLE, &val); |
| if (val) |
| frame->Capabilities.shortPreamble = 1; |
| |
| wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED, &val); |
| if (val) |
| frame->Capabilities.spectrumMgt = 1; |
| |
| wlan_cfg_get_int(mac_ctx, WNI_CFG_QOS_ENABLED, &val); |
| if (val) |
| frame->Capabilities.qos = 1; |
| |
| wlan_cfg_get_int(mac_ctx, WNI_CFG_APSD_ENABLED, &val); |
| if (val) |
| frame->Capabilities.apsd = 1; |
| |
| wlan_cfg_get_int(mac_ctx, WNI_CFG_BLOCK_ACK_ENABLED, &val); |
| frame->Capabilities.delayedBA = |
| (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1); |
| frame->Capabilities.immediateBA = |
| (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1); |
| |
| /* Country */ |
| item = WNI_CFG_MAX_TX_POWER_5; |
| CFG_GET_STR(nSirStatus, mac_ctx, item, temp, len, |
| WNI_CFG_MAX_TX_POWER_5_LEN); |
| wlan_reg_read_current_country(mac_ctx->psoc, code); |
| qdf_mem_copy(&frame->Country, code, 2); |
| if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) |
| len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; |
| |
| frame->Country.num_triplets = (uint8_t)(len / 3); |
| qdf_mem_copy((uint8_t *)&frame->Country.triplets, temp, len); |
| frame->Country.present = 1; |
| |
| /* PowerConstraints */ |
| wlan_cfg_get_int(mac_ctx, WNI_CFG_LOCAL_POWER_CONSTRAINT, &val); |
| frame->PowerConstraints.localPowerConstraints = (uint8_t)val; |
| frame->PowerConstraints.present = 1; |
| |
| /* TimeAdvertisement */ |
| frame->TimeAdvertisement.present = 1; |
| frame->TimeAdvertisement.timing_capabilities = 1; |
| |
| return nSirStatus; |
| } |
| |
| #ifdef WLAN_FEATURE_11AX |
| /** |
| * populate_dot11f_he_caps() - pouldate HE Capability IE |
| * @mac_ctx: Global MAC context |
| * @session: PE session |
| * @he_cap: pointer to HE capability IE |
| * |
| * Populdate the HE capability IE based on the session. |
| */ |
| QDF_STATUS populate_dot11f_he_caps(tpAniSirGlobal mac_ctx, tpPESession session, |
| tDot11fIEhe_cap *he_cap) |
| { |
| uint8_t *ppet; |
| uint32_t value = 0; |
| QDF_STATUS status; |
| |
| he_cap->present = 1; |
| |
| if (!session) { |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CONTROL, value); |
| he_cap->htc_he = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TWT_REQUESTOR, value); |
| he_cap->twt_request = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TWT_RESPONDER, value); |
| he_cap->twt_responder = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_FRAGMENTATION, value); |
| he_cap->fragmentation = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MAX_FRAG_MSDU, value); |
| he_cap->max_num_frag_msdu = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MIN_FRAG_SIZE, value); |
| he_cap->min_frag_size = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TRIG_PAD, value); |
| he_cap->trigger_frm_mac_pad = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MTID_AGGR, value); |
| he_cap->multi_tid_aggr = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LINK_ADAPTATION, value); |
| he_cap->he_link_adaptation = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ALL_ACK, value); |
| he_cap->all_ack = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_UL_MU_RSP_SCHEDULING, |
| value); |
| he_cap->ul_mu_rsp_sched = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BUFFER_STATUS_RPT, |
| value); |
| he_cap->a_bsr = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BCAST_TWT, value); |
| he_cap->broadcast_twt = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BA_32BIT, value); |
| he_cap->ba_32bit_bitmap = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MU_CASCADING, value); |
| he_cap->mu_cascade = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MULTI_TID, value); |
| he_cap->ack_enabled_multitid = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DL_MU_BA, value); |
| he_cap->dl_mu_ba = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_OMI, value); |
| he_cap->omi_a_ctrl = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_OFDMA_RA, value); |
| he_cap->ofdma_ra = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MAX_AMPDU_LEN, value); |
| he_cap->max_ampdu_len = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_AMSDU_FRAG, value); |
| he_cap->amsdu_frag = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_FLEX_TWT_SCHED, value); |
| he_cap->flex_twt_sched = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_CTRL, value); |
| he_cap->rx_ctrl_frame = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BSRP_AMPDU_AGGR, value); |
| he_cap->bsrp_ampdu_aggr = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_QTP, value); |
| he_cap->qtp = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_A_BQR, value); |
| he_cap->a_bqr = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SR_RESPONDER, value); |
| he_cap->sr_responder = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_NDP_FEEDBACK_SUPP, |
| value); |
| he_cap->ndp_feedback_supp = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_OPS_SUPP, value); |
| he_cap->ops_supp = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_AMSDU_IN_AMPDU, value); |
| he_cap->amsdu_in_ampdu = value; |
| |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DUAL_BAND, value); |
| he_cap->dual_band = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CHAN_WIDTH, value); |
| he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(value, 0); |
| he_cap->chan_width_1 = HE_CH_WIDTH_GET_BIT(value, 1); |
| he_cap->chan_width_2 = HE_CH_WIDTH_GET_BIT(value, 2); |
| he_cap->chan_width_3 = HE_CH_WIDTH_GET_BIT(value, 3); |
| he_cap->chan_width_4 = HE_CH_WIDTH_GET_BIT(value, 4); |
| he_cap->chan_width_5 = HE_CH_WIDTH_GET_BIT(value, 5); |
| he_cap->chan_width_6 = HE_CH_WIDTH_GET_BIT(value, 6); |
| |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_PREAM_PUNC, value); |
| he_cap->rx_pream_puncturing = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CLASS_OF_DEVICE, value); |
| he_cap->device_class = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LDPC, value); |
| he_cap->ldpc_coding = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LTF_PPDU, value); |
| he_cap->he_1x_ltf_800_gi_ppdu = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_MIDAMBLE_RX_MAX_NSTS, value); |
| he_cap->midamble_rx_max_nsts = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_LTF_NDP, value); |
| he_cap->he_4x_ltf_3200_gi_ndp = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TX_STBC_LT80, value); |
| he_cap->tx_stbc_lt_80mhz = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_STBC_LT80, value); |
| he_cap->rx_stbc_lt_80mhz = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DOPPLER, value); |
| he_cap->doppler = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_UL_MUMIMO, value); |
| he_cap->ul_mu = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DCM_TX, value); |
| he_cap->dcm_enc_tx = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DCM_RX, value); |
| he_cap->dcm_enc_rx = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MU_PPDU, value); |
| he_cap->ul_he_mu = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SU_BEAMFORMER, value); |
| he_cap->su_beamformer = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SU_BEAMFORMEE, value); |
| he_cap->su_beamformee = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MU_BEAMFORMER, value); |
| he_cap->mu_beamformer = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BFEE_STS_LT80, value); |
| he_cap->bfee_sts_lt_80 = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BFEE_STS_GT80, value); |
| he_cap->bfee_sts_gt_80 = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_NUM_SOUND_LT80, value); |
| he_cap->num_sounding_lt_80 = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_NUM_SOUND_GT80, value); |
| he_cap->num_sounding_gt_80 = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SU_FEED_TONE16, value); |
| he_cap->su_feedback_tone16 = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MU_FEED_TONE16, value); |
| he_cap->mu_feedback_tone16 = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CODEBOOK_SU, value); |
| he_cap->codebook_su = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_CODEBOOK_MU, value); |
| he_cap->codebook_mu = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_BFRM_FEED, value); |
| he_cap->beamforming_feedback = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ER_SU_PPDU, value); |
| he_cap->he_er_su_ppdu = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_DL_PART_BW, value); |
| he_cap->dl_mu_mimo_part_bw = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_PPET_PRESENT, value); |
| he_cap->ppet_present = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_SRP, value); |
| he_cap->srp = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_POWER_BOOST, value); |
| he_cap->power_boost = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_4x_LTF_GI, value); |
| he_cap->he_ltf_800_gi_4x = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_MAX_NC, value); |
| he_cap->max_nc = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TX_STBC_GT80, value); |
| he_cap->tx_stbc_gt_80mhz = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_STBC_GT80, value); |
| he_cap->rx_stbc_gt_80mhz = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ER_4x_LTF_GI, value); |
| he_cap->er_he_ltf_800_gi_4x = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_PPDU_20_IN_40MHZ_2G, value); |
| he_cap->he_ppdu_20_in_40Mhz_2G = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_PPDU_20_IN_160_80P80MHZ, value); |
| he_cap->he_ppdu_20_in_160_80p80Mhz = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_PPDU_80_IN_160_80P80MHZ, value); |
| he_cap->he_ppdu_80_in_160_80p80Mhz = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_ER_1X_HE_LTF_GI, value); |
| he_cap->er_1x_he_ltf_gi = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_MIDAMBLE_RX_1X_HE_LTF, value); |
| he_cap->midamble_rx_1x_he_ltf = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_RX_MCS_MAP_LT_80, value); |
| he_cap->rx_he_mcs_map_lt_80 = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_TX_MCS_MAP_LT_80, value); |
| he_cap->tx_he_mcs_map_lt_80 = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_RX_MCS_MAP_160, value); |
| *((uint16_t *)he_cap->rx_he_mcs_map_160) = value; |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_HE_TX_MCS_MAP_160, value); |
| *((uint16_t *)he_cap->tx_he_mcs_map_160) = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_RX_MCS_MAP_80_80, value); |
| *((uint16_t *)he_cap->rx_he_mcs_map_80_80) = value; |
| CFG_GET_INT(status, mac_ctx, |
| WNI_CFG_HE_TX_MCS_MAP_80_80, value); |
| *((uint16_t *)he_cap->tx_he_mcs_map_80_80) = value; |
| |
| if (he_cap->ppet_present) { |
| value = WNI_CFG_HE_PPET_LEN; |
| /* if session less then take 5g cap */ |
| CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_5G, |
| he_cap->ppet.ppe_threshold.ppe_th, |
| value, value); |
| ppet = he_cap->ppet.ppe_threshold.ppe_th; |
| he_cap->ppet.ppe_threshold.num_ppe_th = |
| lim_truncate_ppet(ppet, value); |
| } else { |
| he_cap->ppet.ppe_threshold.num_ppe_th = 0; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| qdf_mem_copy(he_cap, &session->he_config, sizeof(*he_cap)); |
| if (he_cap->ppet_present) { |
| value = WNI_CFG_HE_PPET_LEN; |
| /* if session is present, populate PPET based on band */ |
| if (IS_5G_CH(session->currentOperChannel)) |
| CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_5G, |
| he_cap->ppet.ppe_threshold.ppe_th, |
| value, value); |
| else |
| CFG_GET_STR(status, mac_ctx, WNI_CFG_HE_PPET_2G, |
| he_cap->ppet.ppe_threshold.ppe_th, |
| value, value); |
| ppet = he_cap->ppet.ppe_threshold.ppe_th; |
| he_cap->ppet.ppe_threshold.num_ppe_th = |
| lim_truncate_ppet(ppet, value); |
| } else { |
| he_cap->ppet.ppe_threshold.num_ppe_th = 0; |
| } |
| |
| lim_log_he_cap(mac_ctx, he_cap); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * populate_dot11f_he_operation() - pouldate HE Operation IE |
| * @mac_ctx: Global MAC context |
| * @session: PE session |
| * @he_op: pointer to HE Operation IE |
| * |
| * Populdate the HE Operation IE based on the session. |
| */ |
| QDF_STATUS |
| populate_dot11f_he_operation(tpAniSirGlobal mac_ctx, |
| tpPESession session, tDot11fIEhe_op *he_op) |
| { |
| qdf_mem_copy(he_op, &session->he_op, sizeof(*he_op)); |
| |
| he_op->vht_oper_present = 1; |
| he_op->present = 1; |
| if (session->ch_width > CH_WIDTH_40MHZ) { |
| he_op->vht_oper.info.chan_width = 1; |
| he_op->vht_oper.info.center_freq_seg0 = |
| session->ch_center_freq_seg0; |
| if (session->ch_width == CH_WIDTH_80P80MHZ || |
| session->ch_width == CH_WIDTH_160MHZ) |
| he_op->vht_oper.info.center_freq_seg1 = |
| session->ch_center_freq_seg1; |
| else |
| he_op->vht_oper.info.center_freq_seg1 = 0; |
| } else { |
| he_op->vht_oper.info.chan_width = 0; |
| he_op->vht_oper.info.center_freq_seg0 = 0; |
| he_op->vht_oper.info.center_freq_seg1 = 0; |
| } |
| lim_log_he_op(mac_ctx, he_op); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| #ifdef WLAN_FEATURE_11AX_BSS_COLOR |
| /** |
| * populate_dot11f_he_bss_color_change() - pouldate HE BSS color change IE |
| * @mac_ctx: Global MAC context |
| * @session: PE session |
| * @he_bss_color: pointer to HE BSS color change IE |
| * |
| * Populdate the HE BSS color change IE based on the session. |
| */ |
| QDF_STATUS |
| populate_dot11f_he_bss_color_change(tpAniSirGlobal mac_ctx, |
| tpPESession session, |
| tDot11fIEbss_color_change *he_bss_color) |
| { |
| if (!session->bss_color_changing) { |
| he_bss_color->present = 0; |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| he_bss_color->present = 1; |
| he_bss_color->countdown = session->he_bss_color_change.countdown; |
| he_bss_color->new_color = session->he_bss_color_change.new_color; |
| |
| lim_log_he_bss_color(mac_ctx, he_bss_color); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif |
| #endif |
| |
| #ifdef WLAN_SUPPORT_TWT |
| QDF_STATUS populate_dot11f_twt_extended_caps(tpAniSirGlobal mac_ctx, |
| tpPESession pe_session, |
| tDot11fIEExtCap *dot11f) |
| { |
| uint32_t value = 0; |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| struct s_ext_cap *p_ext_cap; |
| |
| dot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN; |
| p_ext_cap = (struct s_ext_cap *)dot11f->bytes; |
| |
| if (pe_session->pePersona == QDF_STA_MODE) { |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_TWT_REQUESTOR, value); |
| p_ext_cap->twt_requestor_support = value; |
| } |
| if (pe_session->pePersona == QDF_SAP_MODE) { |
| CFG_GET_INT(status, mac_ctx, WNI_CFG_TWT_RESPONDER, value); |
| p_ext_cap->twt_responder_support = value; |
| } |
| dot11f->num_bytes = lim_compute_ext_cap_ie_length(dot11f); |
| |
| return status; |
| } |
| #endif |
| |
| /* parser_api.c ends here. */ |