diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index afa4198dad3f..1c4a8e335c42 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -4533,12 +4533,23 @@ QDF_STATUS csr_roam_prepare_bss_config(tpAniSirGlobal pMac, pProfile, &cfgDot11Mode, pIes)) { pBssConfig->uCfgDot11Mode = cfgDot11Mode; } else { + /* + * No matching phy mode found, force to 11b/g based on INI for + * 2.4Ghz and to 11a mode for 5Ghz + */ sme_warn("Can not find match phy mode"); - /* force it */ - if (BAND_2G == pBssConfig->eBand) - pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; - else + if (BAND_2G == pBssConfig->eBand) { + if (pMac->roam.configParam.phyMode & + (eCSR_DOT11_MODE_11b | eCSR_DOT11_MODE_11b_ONLY)) { + pBssConfig->uCfgDot11Mode = + eCSR_CFG_DOT11_MODE_11B; + } else { + pBssConfig->uCfgDot11Mode = + eCSR_CFG_DOT11_MODE_11G; + } + } else { pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } } sme_debug("phyMode=%d, uCfgDot11Mode=%d negotiatedAuthType %d", diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 1579b746449e..fd0aa4e082a9 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -1698,10 +1698,13 @@ uint32_t csr_get_rts_thresh(tpAniSirGlobal mac_ctx) return mac_ctx->mlme_cfg->threshold.rts_threshold; } -static eCsrPhyMode csr_translate_to_phy_mode_from_bss_desc( - tSirBssDescription *pSirBssDesc) +static eCsrPhyMode +csr_translate_to_phy_mode_from_bss_desc(tpAniSirGlobal mac_ctx, + tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *ies) { eCsrPhyMode phyMode; + uint8_t i; switch (pSirBssDesc->nwType) { case eSIR_11A_NW_TYPE: @@ -1713,9 +1716,23 @@ static eCsrPhyMode csr_translate_to_phy_mode_from_bss_desc( break; case eSIR_11G_NW_TYPE: - phyMode = eCSR_DOT11_MODE_11g; - break; + phyMode = eCSR_DOT11_MODE_11g_ONLY; + /* Check if the BSS is in b/g mixed mode or g_only mode */ + if (!ies || !ies->SuppRates.present) { + sme_debug("Unable to get rates, assume G only mode"); + break; + } + + for (i = 0; i < ies->SuppRates.num_rates; i++) { + if (csr_rates_is_dot11_rate11b_supported_rate( + ies->SuppRates.rates[i])) { + sme_debug("One B rate is supported"); + phyMode = eCSR_DOT11_MODE_11g; + break; + } + } + break; case eSIR_11N_NW_TYPE: phyMode = eCSR_DOT11_MODE_11n; break; @@ -1821,7 +1838,8 @@ QDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac, { QDF_STATUS status = QDF_STATUS_SUCCESS; eCsrPhyMode phyMode = - csr_translate_to_phy_mode_from_bss_desc(pBSSDescription); + csr_translate_to_phy_mode_from_bss_desc(pMac, pBSSDescription, + pIes); if (pIes) { if (pIes->HTCaps.present) { @@ -1851,7 +1869,8 @@ QDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac, * * Return: true or false */ -static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, +static bool csr_get_phy_mode_in_use(tpAniSirGlobal mac_ctx, + eCsrPhyMode phyModeIn, eCsrPhyMode bssPhyMode, bool f5GhzBand, enum csr_cfgdot11mode *pCfgDot11ModeToUse) @@ -1890,21 +1909,16 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, break; case eCSR_DOT11_MODE_11g_ONLY: - if (eCSR_DOT11_MODE_11g == bssPhyMode) { + if ((bssPhyMode == eCSR_DOT11_MODE_11g) || + (bssPhyMode == eCSR_DOT11_MODE_11g_ONLY)) { fMatch = true; cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; } break; case eCSR_DOT11_MODE_11b: - if (!f5GhzBand) { - fMatch = true; - cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; - } - break; - case eCSR_DOT11_MODE_11b_ONLY: - if (eCSR_DOT11_MODE_11b == bssPhyMode) { + if (!f5GhzBand && (bssPhyMode != eCSR_DOT11_MODE_11g_ONLY)) { fMatch = true; cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; } @@ -1914,6 +1928,7 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, fMatch = true; switch (bssPhyMode) { case eCSR_DOT11_MODE_11g: + case eCSR_DOT11_MODE_11g_ONLY: cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; break; case eCSR_DOT11_MODE_11b: @@ -1946,6 +1961,7 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, fMatch = true; switch (bssPhyMode) { case eCSR_DOT11_MODE_11g: + case eCSR_DOT11_MODE_11g_ONLY: cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; break; case eCSR_DOT11_MODE_11b: @@ -1975,6 +1991,7 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, fMatch = true; switch (bssPhyMode) { case eCSR_DOT11_MODE_11g: + case eCSR_DOT11_MODE_11g_ONLY: cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; break; case eCSR_DOT11_MODE_11b: @@ -2007,6 +2024,7 @@ static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, fMatch = true; switch (bssPhyMode) { case eCSR_DOT11_MODE_11g: + case eCSR_DOT11_MODE_11g_ONLY: cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; break; case eCSR_DOT11_MODE_11b: @@ -2106,19 +2124,21 @@ bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode, } else { phyMode2 = phyMode; } - fMatch = csr_get_phy_mode_in_use(phyMode2, phyModeInBssDesc, - WLAN_REG_IS_5GHZ_CH(pSirBssDesc->channelId), - &cfgDot11ModeToUse); + fMatch = csr_get_phy_mode_in_use(pMac, phyMode2, + phyModeInBssDesc, + WLAN_REG_IS_5GHZ_CH( + pSirBssDesc->channelId), + &cfgDot11ModeToUse); } else { bitMask = 1; loopCount = 0; while (loopCount < eCSR_NUM_PHY_MODE) { phyMode2 = (phyMode & (bitMask << loopCount++)); - if (0 != phyMode2 && csr_get_phy_mode_in_use(phyMode2, - phyModeInBssDesc, - WLAN_REG_IS_5GHZ_CH - (pSirBssDesc->channelId), - &cfgDot11ModeToUse)) { + if (0 != phyMode2 && + csr_get_phy_mode_in_use(pMac, phyMode2, + phyModeInBssDesc, + WLAN_REG_IS_5GHZ_CH(pSirBssDesc->channelId), + &cfgDot11ModeToUse)) { fMatch = true; break; }