From 78f654bcc573e7846c1d2e757864caee2ba3a6e6 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 29 Aug 2018 12:23:00 +0530 Subject: [PATCH] qcacld-3.0: Validate cbmode and bw provided by AP in HTinfo IE Driver checks if 40 Mhz is supported for the channel but doesn't validate if the cbmode provided by AP is valid. Invalid cb mode provided by AP can lead to failure. Add check to validate cbmode and bandwidth from AP in htinfo IE. Change-Id: I3d2da7a8e3045594baf201732dd80a82bd88e16c CRs-Fixed: 2303267 --- core/sme/inc/csr_api.h | 2 ++ core/sme/src/csr/csr_api_roam.c | 33 +++++++++++++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 62266426a087..0b325d469b07 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -666,6 +666,8 @@ typedef enum { */ #define CSR_CB_CHANNEL_GAP 4 #define CSR_CB_CENTER_CHANNEL_OFFSET 2 +#define CSR_SEC_CHANNEL_OFFSET 4 + /* WEP keysize (in bits) */ typedef enum { diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 58070409d879..6b8052b0ea88 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -13790,15 +13790,15 @@ bool csr_roam_is_channel_valid(tpAniSirGlobal pMac, uint8_t channel) /* This function check and validate whether the NIC can do CB (40MHz) */ static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac, - uint8_t primaryChn, + uint8_t chan, tDot11fBeaconIEs *pIes) { ePhyChanBondState eRet = PHY_SINGLE_CHANNEL_CENTERED; - uint8_t centerChn; + uint8_t sec_ch = 0; uint32_t ChannelBondingMode; struct ch_params ch_params = {0}; - if (WLAN_REG_IS_24GHZ_CH(primaryChn)) { + if (WLAN_REG_IS_24GHZ_CH(chan)) { ChannelBondingMode = pMac->roam.configParam.channelBondingMode24GHz; } else { @@ -13838,7 +13838,7 @@ static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac, * value of supported channel width and recommended tx width as per * standard */ - sme_debug("scws %u rtws %u sco %u", + sme_debug("chan %d scws %u rtws %u sco %u", chan, pIes->HTCaps.supportedChannelWidthSet, pIes->HTInfo.recommendedTxWidthSet, pIes->HTInfo.secondaryChannelOffset); @@ -13850,28 +13850,29 @@ static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac, switch (eRet) { case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: - centerChn = primaryChn + CSR_CB_CENTER_CHANNEL_OFFSET; + sec_ch = chan + CSR_SEC_CHANNEL_OFFSET; break; case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: - centerChn = primaryChn - CSR_CB_CENTER_CHANNEL_OFFSET; + sec_ch = chan - CSR_SEC_CHANNEL_OFFSET; break; - case PHY_SINGLE_CHANNEL_CENTERED: default: - centerChn = primaryChn; break; } - if (PHY_SINGLE_CHANNEL_CENTERED != eRet) { - ch_params.ch_width = CH_WIDTH_MAX; - - wlan_reg_set_channel_params(pMac->pdev, primaryChn, - 0, &ch_params); - if (ch_params.ch_width == CH_WIDTH_20MHZ) { - sme_err("40Mhz not supported for channel %d, continue with 20Mhz", - centerChn); + if (eRet != PHY_SINGLE_CHANNEL_CENTERED) { + ch_params.ch_width = CH_WIDTH_40MHZ; + wlan_reg_set_channel_params(pMac->pdev, chan, + sec_ch, &ch_params); + if (ch_params.ch_width == CH_WIDTH_20MHZ || + ch_params.sec_ch_offset != eRet) { + sme_err("chan %d :: Supported HT BW %d and cbmode %d, APs HT BW %d and cbmode %d, so switch to 20Mhz", + chan, ch_params.ch_width, + ch_params.sec_ch_offset, + pIes->HTInfo.recommendedTxWidthSet, eRet); eRet = PHY_SINGLE_CHANNEL_CENTERED; } } + return eRet; }