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; }