diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 5d0159c37da9..982dfc096633 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -300,6 +300,30 @@ enum hdd_dot11_mode { #define CFG_CHANNEL_BONDING_MODE_MAX WNI_CFG_CHANNEL_BONDING_MODE_STAMAX #define CFG_CHANNEL_BONDING_MODE_DEFAULT WNI_CFG_CHANNEL_BONDING_MODE_STADEF +/* + * + * override_ht20_40_24g - use channel Bonding in 24 GHz from supplicant + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to use channel Bonding in 24 GHz from supplicant if + * gChannelBondingMode24GHz is set + * + * Related: gChannelBondingMode24GHz + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * + */ + +#define CFG_OVERRIDE_HT40_20_24GHZ_NAME "override_ht20_40_24g" +#define CFG_OVERRIDE_HT40_20_24GHZ_MIN 0 +#define CFG_OVERRIDE_HT40_20_24GHZ_MAX 1 +#define CFG_OVERRIDE_HT40_20_24GHZ_DEFAULT 0 + /* * * gChannelBondingMode5GHz - Configures Channel Bonding in 5 GHz @@ -11568,6 +11592,7 @@ struct hdd_config { uint32_t nBmpsMinListenInterval; enum hdd_dot11_mode dot11Mode; uint32_t nChannelBondingMode24GHz; + bool override_ht20_40_24g; uint32_t nChannelBondingMode5GHz; uint32_t MaxRxAmpduFactor; uint16_t TxRate; diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index b9ff033f3e21..f898db0cba3a 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -481,6 +481,13 @@ struct reg_table_entry g_registry_table[] = { CFG_CHANNEL_BONDING_MODE_MIN, CFG_CHANNEL_BONDING_MODE_MAX), + REG_VARIABLE(CFG_OVERRIDE_HT40_20_24GHZ_NAME, WLAN_PARAM_Integer, + struct hdd_config, override_ht20_40_24g, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OVERRIDE_HT40_20_24GHZ_DEFAULT, + CFG_OVERRIDE_HT40_20_24GHZ_MIN, + CFG_OVERRIDE_HT40_20_24GHZ_MAX), + REG_VARIABLE(CFG_CHANNEL_BONDING_MODE_5GHZ_NAME, WLAN_PARAM_Integer, struct hdd_config, nChannelBondingMode5GHz, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, @@ -5646,6 +5653,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) pHddCtx->config->sap_p2p_11ac_override); hdd_debug("Name = [ChannelBondingMode] Value = [%u]", pHddCtx->config->nChannelBondingMode24GHz); + hdd_debug("Name = [%s] Value = [%u] ", + CFG_OVERRIDE_HT40_20_24GHZ_NAME, + pHddCtx->config->override_ht20_40_24g); hdd_debug("Name = [ChannelBondingMode] Value = [%u]", pHddCtx->config->nChannelBondingMode5GHz); hdd_debug("Name = [dot11Mode] Value = [%u]", diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 7af07645542e..9d9b26b7203d 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -16002,6 +16002,55 @@ static bool wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter, } #endif + +/** + * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to + * connect in HT20 mode + * @hdd_ctx: hdd context + * @adapter: Pointer to the HDD adapter + * @req: Pointer to the structure cfg_connect_params receieved from user space + * + * This function will check if supplicant has indicated to to connect in HT20 + * mode. this is currently applicable only for 2.4Ghz mode only. + * if feature is enabled and supplicant indicate HT20 set + * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false. + * + * Return: void + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) +static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter, + struct cfg80211_connect_params *req) +{ + hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter); + tCsrRoamProfile *roam_profile; + + roam_profile = &wext_state->roamProfile; + roam_profile->force_24ghz_in_ht20 = false; + + if (hdd_ctx->config->override_ht20_40_24g && + !(req->ht_capa.cap_info & + IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + roam_profile->force_24ghz_in_ht20 = true; + + hdd_debug("req->ht_capa.cap_info %x override_ht20_40_24g %d", + req->ht_capa.cap_info, + hdd_ctx->config->override_ht20_40_24g); +} +#else +static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter, + struct cfg80211_connect_params *req) +{ + hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter); + tCsrRoamProfile *roam_profile; + + roam_profile = &wext_state->roamProfile; + + roam_profile->force_24ghz_in_ht20 = false; +} +#endif + /** * __wlan_hdd_cfg80211_connect() - cfg80211 connect api * @wiphy: Pointer to wiphy @@ -16150,6 +16199,9 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, channel = req->channel->hw_value; else channel = 0; + + wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req); + status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid, req->ssid_len, req->bssid, bssid_hint, channel, 0); diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 840cec0cc75b..75e2c302953a 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -1246,6 +1246,7 @@ typedef struct sSirSmeJoinReq { struct cds_fils_connection_info fils_con_info; #endif /* Pls make this as last variable in struct */ + bool force_24ghz_in_ht20; tSirBssDescription bssDescription; /* * WARNING: Pls make bssDescription as last variable in struct diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 54cbe04b9422..5d0d244249cd 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -518,6 +518,7 @@ typedef struct sPESession /* Added to Support BT-AMP */ #endif bool enable_bcast_probe_rsp; uint8_t ht_client_cnt; + bool force_24ghz_in_ht20; bool ch_switch_in_progress; #ifdef WLAN_FEATURE_FILS_SK struct pe_fils_session *fils_info; diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index ac831c229ac0..f8b3128f3b26 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -1686,9 +1686,10 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) /*Store Persona */ session->pePersona = sme_join_req->staPersona; QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, - FL("PE PERSONA=%d cbMode %u nwType: %d dot11mode: %d"), + FL("PE PERSONA=%d cbMode %u nwType: %d dot11mode: %d force_24ghz_in_ht20 %d"), session->pePersona, sme_join_req->cbMode, - session->nwType, session->dot11mode); + session->nwType, session->dot11mode, + sme_join_req->force_24ghz_in_ht20); /* Copy The channel Id to the session Table */ session->currentOperChannel = bss_desc->channelId; @@ -1731,6 +1732,8 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) /*Phy mode */ session->gLimPhyMode = bss_desc->nwType; handle_ht_capabilityand_ht_info(mac_ctx, session); + session->force_24ghz_in_ht20 = + sme_join_req->force_24ghz_in_ht20; /* cbMode is already merged value of peer and self - * done by csr in csr_get_cb_mode_from_ies */ session->htSupportedChannelWidthSet = diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index a3363eda6178..e4b13012a541 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -4371,6 +4371,12 @@ void lim_update_sta_run_time_ht_switch_chnl_params(tpAniSirGlobal pMac, (pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry)) return; + if (WLAN_REG_IS_24GHZ_CH(psessionEntry->currentOperChannel) && + psessionEntry->force_24ghz_in_ht20) { + pe_debug("force_24ghz_in_ht20 is set and channel is 2.4 Ghz"); + return; + } + if (psessionEntry->ftPEContext.ftPreAuthSession) { pe_err("FT PREAUTH channel change is in progress"); return; diff --git a/core/mac/src/pe/sch/sch_beacon_process.c b/core/mac/src/pe/sch/sch_beacon_process.c index c9f88b6a717a..7bcbe9f127c2 100644 --- a/core/mac/src/pe/sch/sch_beacon_process.c +++ b/core/mac/src/pe/sch/sch_beacon_process.c @@ -684,9 +684,13 @@ sch_bcn_process_sta_ibss(tpAniSirGlobal mac_ctx, uint16_t aid; uint8_t cb_mode; - if (CHAN_ENUM_14 >= session->currentOperChannel) - cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz; - else + if (CHAN_ENUM_14 >= session->currentOperChannel) { + if (session->force_24ghz_in_ht20) + cb_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + else + cb_mode = + mac_ctx->roam.configParam.channelBondingMode24GHz; + } else cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz; /* check for VHT capability */ pStaDs = dph_lookup_hash_entry(mac_ctx, pMh->sa, &aid, diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 630db794ad4f..f843636e7771 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -1000,6 +1000,7 @@ typedef struct tagCsrRoamProfile { tSirMacRateSet supported_rates; tSirMacRateSet extended_rates; struct qdf_mac_addr bssid_hint; + bool force_24ghz_in_ht20; bool do_not_roam; uint32_t cac_duration_ms; uint32_t dfs_regdomain; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 112fb0099c47..69de06ccadd0 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -4328,6 +4328,12 @@ QDF_STATUS csr_roam_prepare_bss_config(tpAniSirGlobal pMac, else pBssConfig->cbMode = PHY_SINGLE_CHANNEL_CENTERED; + if (WLAN_REG_IS_24GHZ_CH(pBssDesc->channelId) && + pProfile->force_24ghz_in_ht20) { + pBssConfig->cbMode = PHY_SINGLE_CHANNEL_CENTERED; + sme_debug("force_24ghz_in_ht20 is set so set cbmode to 0"); + } + return QDF_STATUS_SUCCESS; } @@ -7848,6 +7854,7 @@ QDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac, /*Save the WPS info */ pDstProfile->bWPSAssociation = pSrcProfile->bWPSAssociation; pDstProfile->bOSENAssociation = pSrcProfile->bOSENAssociation; + pDstProfile->force_24ghz_in_ht20 = pSrcProfile->force_24ghz_in_ht20; pDstProfile->uapsd_mask = pSrcProfile->uapsd_mask; pDstProfile->beaconInterval = pSrcProfile->beaconInterval; pDstProfile->privacy = pSrcProfile->privacy; @@ -14715,8 +14722,11 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, csr_join_req->staPersona = (uint8_t) pProfile->csrPersona; csr_join_req->wps_registration = pProfile->bWPSAssociation; csr_join_req->cbMode = (uint8_t) pSession->bssParams.cbMode; - sme_debug("CSR PERSONA: %d CSR CbMode: %d", - pProfile->csrPersona, pSession->bssParams.cbMode); + csr_join_req->force_24ghz_in_ht20 = + pProfile->force_24ghz_in_ht20; + sme_debug("CSR PERSONA: %d CSR CbMode: %d force 24gh ht20 %d", + pProfile->csrPersona, pSession->bssParams.cbMode, + csr_join_req->force_24ghz_in_ht20); csr_join_req->uapsdPerAcBitmask = pProfile->uapsd_mask; pSession->uapsd_mask = pProfile->uapsd_mask; status =