From 02b9aa4bba444b9673b68959ab4519aedf039e95 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Thu, 26 May 2016 14:54:49 -0700 Subject: [PATCH] qcacld-3.0: Add support to parse new vht op IE definition VHT channel width definition is changed in latest draft. Add support to parse the new definition of VHT channel width in VHT operation IE. Change-Id: I1b9ece6ad490cc158df87d86035a0a338008c539 CRs-Fixed: 1022680 --- core/mac/src/pe/lim/lim_prop_exts_utils.c | 275 +++++++++++++--------- core/wma/src/wma_dev_if.c | 6 +- core/wma/src/wma_utils.c | 6 +- 3 files changed, 177 insertions(+), 110 deletions(-) diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.c b/core/mac/src/pe/lim/lim_prop_exts_utils.c index 68d3961f1353..268a2c18ed1d 100644 --- a/core/mac/src/pe/lim/lim_prop_exts_utils.c +++ b/core/mac/src/pe/lim/lim_prop_exts_utils.c @@ -81,6 +81,12 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie, uint32_t enable_txbf_20mhz; tSirRetStatus cfg_set_status = eSIR_FAILURE; tSirRetStatus cfg_get_status = eSIR_FAILURE; + uint8_t ap_bcon_ch_width; + bool new_ch_width_dfn = false; + tDot11fIEVHTOperation *vht_op; + uint8_t fw_vht_ch_wd; + uint8_t vht_ch_wd; + uint8_t center_freq_diff; beacon_struct = qdf_mem_malloc(sizeof(tSirProbeRespBeacon)); if (NULL == beacon_struct) { @@ -96,123 +102,182 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie, FL("In lim_extract_ap_capability: The IE's being received:")); sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG3, p_ie, ie_len); if (sir_parse_beacon_ie(mac_ctx, beacon_struct, p_ie, - (uint32_t) ie_len) == eSIR_SUCCESS) { - if (beacon_struct->wmeInfoPresent - || beacon_struct->wmeEdcaPresent - || beacon_struct->HTCaps.present) - LIM_BSS_CAPS_SET(WME, *qos_cap); - if (LIM_BSS_CAPS_GET(WME, *qos_cap) - && beacon_struct->wsmCapablePresent) - LIM_BSS_CAPS_SET(WSM, *qos_cap); - if (beacon_struct->propIEinfo.capabilityPresent) - *prop_cap = beacon_struct->propIEinfo.capability; - if (beacon_struct->HTCaps.present) - mac_ctx->lim.htCapabilityPresentInBeacon = 1; - else - mac_ctx->lim.htCapabilityPresentInBeacon = 0; + (uint32_t) ie_len) != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, FL( + "sir_parse_beacon_ie failed to parse beacon")); + qdf_mem_free(beacon_struct); + return; + } + if (beacon_struct->wmeInfoPresent || + beacon_struct->wmeEdcaPresent || + beacon_struct->HTCaps.present) + LIM_BSS_CAPS_SET(WME, *qos_cap); + if (LIM_BSS_CAPS_GET(WME, *qos_cap) + && beacon_struct->wsmCapablePresent) + LIM_BSS_CAPS_SET(WSM, *qos_cap); + if (beacon_struct->propIEinfo.capabilityPresent) + *prop_cap = beacon_struct->propIEinfo.capability; + if (beacon_struct->HTCaps.present) + mac_ctx->lim.htCapabilityPresentInBeacon = 1; + else + mac_ctx->lim.htCapabilityPresentInBeacon = 0; - lim_log(mac_ctx, LOG1, - FL("Beacon : VHTCaps.present: %d SU Beamformer: %d, IS_BSS_VHT_CAPABLE: %d"), - beacon_struct->VHTCaps.present, - beacon_struct->VHTCaps.suBeamFormerCap, - IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps)); + lim_log(mac_ctx, LOG1, FL( + "Bcon: VHTCap.present %d SU Beamformer %d BSS_VHT_CAPABLE %d"), + beacon_struct->VHTCaps.present, + beacon_struct->VHTCaps.suBeamFormerCap, + IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps)); - if (IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps) && - beacon_struct->VHTOperation.present && + vht_op = &beacon_struct->VHTOperation; + if (IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps) && + vht_op->present && session->vhtCapability) { - session->vhtCapabilityPresentInBeacon = 1; - if (((beacon_struct->Vendor1IEPresent && - beacon_struct->vendor2_ie.present && - beacon_struct->Vendor3IEPresent)) && - (((beacon_struct->VHTCaps.txMCSMap & - VHT_MCS_3x3_MASK) == VHT_MCS_3x3_MASK) && - ((beacon_struct->VHTCaps.txMCSMap & - VHT_MCS_2x2_MASK) != VHT_MCS_2x2_MASK))) { - session->txBFIniFeatureEnabled = 0; - } - } else { - session->vhtCapabilityPresentInBeacon = 0; + session->vhtCapabilityPresentInBeacon = 1; + if (((beacon_struct->Vendor1IEPresent && + beacon_struct->vendor2_ie.present && + beacon_struct->Vendor3IEPresent)) && + (((beacon_struct->VHTCaps.txMCSMap & VHT_MCS_3x3_MASK) == + VHT_MCS_3x3_MASK) && + ((beacon_struct->VHTCaps.txMCSMap & VHT_MCS_2x2_MASK) != + VHT_MCS_2x2_MASK))) + session->txBFIniFeatureEnabled = 0; + } else { + session->vhtCapabilityPresentInBeacon = 0; + } + + if (session->vhtCapabilityPresentInBeacon == 1 && + session->txBFIniFeatureEnabled == 0) { + cfg_set_status = cfg_set_int(mac_ctx, + WNI_CFG_VHT_SU_BEAMFORMEE_CAP, + 0); + if (cfg_set_status != eSIR_SUCCESS) + lim_log(mac_ctx, LOGP, FL( + "Set VHT_SU_BEAMFORMEE_CAP Fail")); + } + if (session->vhtCapabilityPresentInBeacon == 1 && + !session->htSupportedChannelWidthSet) { + cfg_get_status = wlan_cfg_get_int(mac_ctx, + WNI_CFG_VHT_ENABLE_TXBF_20MHZ, + &enable_txbf_20mhz); + if ((IS_SIR_STATUS_SUCCESS(cfg_get_status)) && + (false == enable_txbf_20mhz)) + session->txBFIniFeatureEnabled = 0; + } else if (session->vhtCapabilityPresentInBeacon && + vht_op->chanWidth) { + /* If VHT is supported min 80 MHz support is must */ + ap_bcon_ch_width = vht_op->chanWidth; + if ((ap_bcon_ch_width == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) && + vht_op->chanCenterFreqSeg2) { + new_ch_width_dfn = true; + if (vht_op->chanCenterFreqSeg2 > + vht_op->chanCenterFreqSeg1) + center_freq_diff = vht_op->chanCenterFreqSeg2 - + vht_op->chanCenterFreqSeg1; + else + center_freq_diff = vht_op->chanCenterFreqSeg1 - + vht_op->chanCenterFreqSeg2; + if (center_freq_diff == 8) + ap_bcon_ch_width = + WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ; + else if (center_freq_diff > 16) + ap_bcon_ch_width = + WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ; } - if (session->vhtCapabilityPresentInBeacon == 1 && - session->txBFIniFeatureEnabled == 0) { - cfg_set_status = cfg_set_int(mac_ctx, - WNI_CFG_VHT_SU_BEAMFORMEE_CAP, - 0); - if (cfg_set_status != eSIR_SUCCESS) - lim_log(mac_ctx, LOGP, - FL("Set VHT_SU_BEAMFORMEE_CAP Fail")); - } - if (session->vhtCapabilityPresentInBeacon == 1 && - !session->htSupportedChannelWidthSet) { - cfg_get_status = wlan_cfg_get_int(mac_ctx, - WNI_CFG_VHT_ENABLE_TXBF_20MHZ, - &enable_txbf_20mhz); - if ((IS_SIR_STATUS_SUCCESS(cfg_get_status)) && - (false == enable_txbf_20mhz)) - session->txBFIniFeatureEnabled = 0; - } else if (session->vhtCapabilityPresentInBeacon == 1 && - beacon_struct->VHTOperation.chanWidth) { - /* If VHT is supported min 80 MHz support is must */ - uint32_t fw_vht_ch_wd = wma_get_vht_ch_width(); - uint32_t vht_ch_wd = QDF_MIN(fw_vht_ch_wd, - beacon_struct->VHTOperation.chanWidth); - if (vht_ch_wd == beacon_struct->VHTOperation.chanWidth - || vht_ch_wd >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) { - /* - * This block covers 2 cases: - * 1) AP and STA both have same vht capab - * 2) AP is 160 (80+80), we are 160 only - */ - session->ch_center_freq_seg0 = - beacon_struct->VHTOperation.chanCenterFreqSeg1; - session->ch_center_freq_seg1 = - beacon_struct->VHTOperation.chanCenterFreqSeg2; + fw_vht_ch_wd = wma_get_vht_ch_width(); + vht_ch_wd = QDF_MIN(fw_vht_ch_wd, ap_bcon_ch_width); + /* + * VHT OP IE old definition: + * vht_op->chanCenterFreqSeg1: center freq of 80MHz/160MHz/ + * primary 80 in 80+80MHz. + * + * vht_op->chanCenterFreqSeg2: center freq of secondary 80 + * in 80+80MHz. + * + * VHT OP IE NEW definition: + * vht_op->chanCenterFreqSeg1: center freq of 80MHz/primary + * 80 in 80+80MHz/center freq of the 80 MHz channel segment + * that contains the primary channel in 160MHz mode. + * + * vht_op->chanCenterFreqSeg2: center freq of secondary 80 + * in 80+80MHz/center freq of 160MHz. + */ + session->ch_center_freq_seg0 = vht_op->chanCenterFreqSeg1; + session->ch_center_freq_seg1 = vht_op->chanCenterFreqSeg2; + if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) { + /* DUT or AP supports only 160MHz */ + if (ap_bcon_ch_width == + WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) { + /* AP is in 160MHz mode */ + if (!new_ch_width_dfn) { + session->ch_center_freq_seg1 = + vht_op->chanCenterFreqSeg1; + session->ch_center_freq_seg0 = + lim_get_80Mhz_center_channel( + beacon_struct->channelNumber); + } } else { - /* when AP was 160 but we were 80 only */ + /* DUT supports only 160MHz and AP is + * in 80+80 mode + */ + vht_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + session->ch_center_freq_seg1 = 0; + } + } else if (vht_ch_wd == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) { + /* DUT or AP supports only 80MHz */ + if (ap_bcon_ch_width == + WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ && + !new_ch_width_dfn) + /* AP is in 160MHz mode */ session->ch_center_freq_seg0 = lim_get_80Mhz_center_channel( beacon_struct->channelNumber); - } - session->ch_width = vht_ch_wd + 1; - if (CH_WIDTH_80MHZ < session->ch_width) { - session->enable_su_tx_bformer = 0; - session->nss = 1; - } + else + session->ch_center_freq_seg1 = 0; } - if (session->vhtCapabilityPresentInBeacon == 1 && - !session->htSupportedChannelWidthSet && - session->txBFIniFeatureEnabled == 0) { - cfg_set_status = cfg_set_int(mac_ctx, - WNI_CFG_VHT_SU_BEAMFORMEE_CAP, - 0); - if (cfg_set_status != eSIR_SUCCESS) - lim_log(mac_ctx, LOGP, - FL("Set VHT_SU_BEAMFORMEE_CAP Fail")); + session->ch_width = vht_ch_wd + 1; + lim_log(mac_ctx, LOGE, FL( + "cntr_freq0 %d, cntr_freq1 %d, width %d"), + session->ch_center_freq_seg0, + session->ch_center_freq_seg1, + session->ch_width); + if (CH_WIDTH_80MHZ < session->ch_width) { + session->enable_su_tx_bformer = 0; + session->nss = 1; } - /* Extract the UAPSD flag from WMM Parameter element */ - if (beacon_struct->wmeEdcaPresent) - *uapsd = beacon_struct->edcaParams.qosInfo.uapsd; -#if defined FEATURE_WLAN_ESE - /* If there is Power Constraint Element specifically, - * adapt to it. Hence there is else condition check - * for this if statement. - */ - if (beacon_struct->eseTxPwr.present) - *local_constraint = beacon_struct->eseTxPwr.power_limit; - session->is_ese_version_ie_present = - beacon_struct->is_ese_ver_ie_present; -#endif - if (beacon_struct->powerConstraintPresent) { - *local_constraint -= - beacon_struct->localPowerConstraint. - localPowerConstraints; - } - session->country_info_present = false; - /* Initializing before first use */ - if (beacon_struct->countryInfoPresent) - session->country_info_present = true; } + if (session->vhtCapabilityPresentInBeacon == 1 && + !session->htSupportedChannelWidthSet && + session->txBFIniFeatureEnabled == 0) { + cfg_set_status = cfg_set_int(mac_ctx, + WNI_CFG_VHT_SU_BEAMFORMEE_CAP, + 0); + if (cfg_set_status != eSIR_SUCCESS) + lim_log(mac_ctx, LOGP, + FL("Set VHT_SU_BEAMFORMEE_CAP Fail")); + } + /* Extract the UAPSD flag from WMM Parameter element */ + if (beacon_struct->wmeEdcaPresent) + *uapsd = beacon_struct->edcaParams.qosInfo.uapsd; +#if defined FEATURE_WLAN_ESE + /* If there is Power Constraint Element specifically, + * adapt to it. Hence there is else condition check + * for this if statement. + */ + if (beacon_struct->eseTxPwr.present) + *local_constraint = beacon_struct->eseTxPwr.power_limit; + session->is_ese_version_ie_present = + beacon_struct->is_ese_ver_ie_present; +#endif + if (beacon_struct->powerConstraintPresent) { + *local_constraint -= + beacon_struct->localPowerConstraint. + localPowerConstraints; + } + session->country_info_present = false; + /* Initializing before first use */ + if (beacon_struct->countryInfoPresent) + session->country_info_present = true; /* Check if Extended caps are present in probe resp or not */ if (beacon_struct->ext_cap.present) session->is_ext_caps_present = true; diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index e5fb871525a5..a588abab4837 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1729,6 +1729,7 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma, uint32_t temp_chan_info = 0; uint32_t temp_reg_info_1 = 0; uint32_t temp_reg_info_2 = 0; + uint16_t bw_val; mac_ctx = cds_get_context(QDF_MODULE_ID_PE); if (mac_ctx == NULL) { @@ -1773,10 +1774,11 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma, params.band_center_freq1 = params.chan_freq; - if (CH_WIDTH_20MHZ != req->chan_width) + bw_val = cds_bw_value(req->chan_width); + if (20 < bw_val) params.band_center_freq1 = cds_chan_to_freq(req->ch_center_freq_seg0); - if (CH_WIDTH_80P80MHZ == req->chan_width) + if (80 < bw_val) params.band_center_freq2 = cds_chan_to_freq(req->ch_center_freq_seg1); else diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index dc6475e1098d..0e607ecb06d9 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -3374,10 +3374,10 @@ uint32_t wma_get_vht_ch_width(void) if (NULL == wm_hdl) return fw_ch_wd; - if (wm_hdl->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_160MHZ) - fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ; - else if (wm_hdl->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ) + if (wm_hdl->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ) fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ; + else if (wm_hdl->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_160MHZ) + fw_ch_wd = WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ; return fw_ch_wd; }