summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaveen Rawat <naveenrawat@codeaurora.org>2016-05-20 10:34:56 -0700
committerVishwajith Upendra <vishwaji@codeaurora.org>2016-08-13 14:07:29 -0700
commit64e477ea40826806a3e50647c4237fac4adf2e62 (patch)
tree3101f07b17c729f1003b97cd54ebb74985f59e71
parentcb23ddd200cabf3fdccd0557a40d79148bae04f1 (diff)
qcacld-3.0: Add support for 5/10 MHz for STA and SAP role
Add support for 5/10 MHz channel width for STA and SAP role. To enable/disable feature, following ini parameter will be used: * gSub20ChannelWidth=0: indicates do not use Sub 20 MHz bandwidth this is also the default value. * gSub20ChannelWidth=1: Bring up SAP/STA in 5 MHz bandwidth * gSub20ChannelWidth=2: Bring up SAP/STA in 10 MHz bandwidth Change-Id: Ic6d534dc1eae60fcd2fb7533c934b9ea28e6dd78 CRs-Fixed: 1013211
-rw-r--r--core/cds/inc/cds_api.h3
-rw-r--r--core/cds/inc/cds_config.h14
-rw-r--r--core/cds/src/cds_api.c66
-rw-r--r--core/cds/src/cds_concurrency.c6
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h10
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c10
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c12
-rw-r--r--core/hdd/src/wlan_hdd_ftm.c1
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c33
-rw-r--r--core/hdd/src/wlan_hdd_main.c14
-rw-r--r--core/mac/src/pe/lim/lim_assoc_utils.c16
-rw-r--r--core/mac/src/pe/lim/lim_process_mlm_req_messages.c8
-rw-r--r--core/mac/src/pe/lim/lim_send_messages.c5
-rw-r--r--core/sme/src/csr/csr_api_roam.c30
-rw-r--r--core/wma/inc/wma.h1
-rw-r--r--core/wma/inc/wma_tgt_cfg.h1
-rw-r--r--core/wma/src/wma_dev_if.c12
-rw-r--r--core/wma/src/wma_main.c5
-rw-r--r--core/wma/src/wma_scan_roam.c6
19 files changed, 242 insertions, 11 deletions
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h
index bb8cf4a58032..8bfddf882dc7 100644
--- a/core/cds/inc/cds_api.h
+++ b/core/cds/inc/cds_api.h
@@ -283,4 +283,7 @@ void cds_init_ini_config(struct cds_config_info *cds_cfg);
void cds_deinit_ini_config(void);
struct cds_config_info *cds_get_ini_config(void);
+bool cds_is_5_mhz_enabled(void);
+bool cds_is_10_mhz_enabled(void);
+bool cds_is_sub_20_mhz_enabled(void);
#endif /* if !defined __CDS_API_H */
diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h
index 5d2eafb9eb9f..4bcb4854cab5 100644
--- a/core/cds/inc/cds_config.h
+++ b/core/cds/inc/cds_config.h
@@ -41,6 +41,17 @@ enum driver_type {
};
/**
+ * enum cfg_sub_20_channel_width: ini values for su 20 mhz channel width
+ * @WLAN_SUB_20_CH_WIDTH_5: Use 5 mhz channel width
+ * @WLAN_SUB_20_CH_WIDTH_10: Use 10 mhz channel width
+ */
+enum cfg_sub_20_channel_width {
+ WLAN_SUB_20_CH_WIDTH_NONE = 0,
+ WLAN_SUB_20_CH_WIDTH_5 = 1,
+ WLAN_SUB_20_CH_WIDTH_10 = 2,
+};
+
+/**
* struct cds_config_info - Place Holder for cds configuration
* @max_station: Max station supported
* @max_bssid: Max Bssid Supported
@@ -82,7 +93,7 @@ enum driver_type {
* @is_nan_enabled: Indicate whether NAN is enabled or not
* @tx_chain_mask_cck: Tx chain mask enabled or not
* @self_gen_frm_pwr: Self gen from power
- *
+ * @sub_20_channel_width: Sub 20 MHz ch width, ini intersected with fw cap
* Structure for holding cds ini parameters.
*/
@@ -131,5 +142,6 @@ struct cds_config_info {
#endif
bool tx_chain_mask_cck;
uint16_t self_gen_frm_pwr;
+ enum cfg_sub_20_channel_width sub_20_channel_width;
};
#endif /* !defined( __CDS_CONFIG_H ) */
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index 82ef025f51c5..c9d66cbd636f 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -2213,3 +2213,69 @@ struct cds_config_info *cds_get_ini_config(void)
return cds_ctx->cds_cfg;
}
+
+/**
+ * cds_is_5_mhz_enabled() - API to get 5MHZ enabled
+ *
+ * Return: true if 5 mhz is enabled, false otherwise
+ */
+bool cds_is_5_mhz_enabled(void)
+{
+ p_cds_contextType p_cds_context;
+
+ p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!p_cds_context) {
+ cds_err("%s: cds context is invalid", __func__);
+ return false;
+ }
+
+ if (p_cds_context->cds_cfg)
+ return (p_cds_context->cds_cfg->sub_20_channel_width ==
+ WLAN_SUB_20_CH_WIDTH_5);
+
+ return false;
+}
+
+/**
+ * cds_is_10_mhz_enabled() - API to get 10-MHZ enabled
+ *
+ * Return: true if 10 mhz is enabled, false otherwise
+ */
+bool cds_is_10_mhz_enabled(void)
+{
+ p_cds_contextType p_cds_context;
+
+ p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!p_cds_context) {
+ cds_err("%s: cds context is invalid", __func__);
+ return false;
+ }
+
+ if (p_cds_context->cds_cfg)
+ return (p_cds_context->cds_cfg->sub_20_channel_width ==
+ WLAN_SUB_20_CH_WIDTH_10);
+
+ return false;
+}
+
+/**
+ * cds_is_sub_20_mhz_enabled() - API to get sub 20-MHZ enabled
+ *
+ * Return: true if 5 or 10 mhz is enabled, false otherwise
+ */
+bool cds_is_sub_20_mhz_enabled(void)
+{
+ p_cds_contextType p_cds_context;
+
+ p_cds_context = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!p_cds_context) {
+ cds_err("%s: cds context is invalid", __func__);
+ return false;
+ }
+
+ if (p_cds_context->cds_cfg)
+ return p_cds_context->cds_cfg->sub_20_channel_width;
+
+ return false;
+}
+
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index 452f1e672f9d..24bd5278ffe3 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -5252,6 +5252,12 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
/* find the current connection state from conc_connection_list*/
num_connections = cds_get_connection_count();
+ if (num_connections && cds_is_sub_20_mhz_enabled()) {
+ /* dont allow concurrency if Sub 20 MHz is enabled */
+ status = false;
+ goto done;
+ }
+
if (cds_max_concurrent_connections_reached()) {
cds_err("Reached max concurrent connections: %d",
hdd_ctx->config->gMaxConcurrentActiveSessions);
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index c8c4ccea759e..b5107787bd7d 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -3399,6 +3399,15 @@ enum dot11p_mode {
#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MAX (4)
#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_DEFAULT (0)
+/*
+ * gSub20ChannelWidth=0: indicates do not use Sub 20 MHz bandwidth
+ * gSub20ChannelWidth=1: Bring up SAP/STA in 5 MHz bandwidth
+ * gSub20ChannelWidth=2: Bring up SAP/STA in 10 MHz bandwidth
+ */
+#define CFG_SUB_20_CHANNEL_WIDTH_NAME "gSub20ChannelWidth"
+#define CFG_SUB_20_CHANNEL_WIDTH_MIN (WLAN_SUB_20_CH_WIDTH_NONE)
+#define CFG_SUB_20_CHANNEL_WIDTH_MAX (WLAN_SUB_20_CH_WIDTH_10)
+#define CFG_SUB_20_CHANNEL_WIDTH_DEFAULT (WLAN_SUB_20_CH_WIDTH_NONE)
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -4058,6 +4067,7 @@ struct hdd_config {
uint8_t nan_datapath_ndi_channel;
#endif
uint32_t iface_change_wait_time;
+ enum cfg_sub_20_channel_width enable_sub_20_channel_width;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index d214ef603e84..88906e4410db 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -3968,6 +3968,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ADAPT_DWELL_LPF_WEIGHT_MIN,
CFG_ADAPT_DWELL_LPF_WEIGHT_MAX),
+ REG_VARIABLE(CFG_SUB_20_CHANNEL_WIDTH_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, enable_sub_20_channel_width,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_SUB_20_CHANNEL_WIDTH_DEFAULT,
+ CFG_SUB_20_CHANNEL_WIDTH_MIN,
+ CFG_SUB_20_CHANNEL_WIDTH_MAX),
+
REG_VARIABLE(CFG_ADAPT_DWELL_PASMON_INTVAL_NAME, WLAN_PARAM_Integer,
struct hdd_config, adapt_dwell_passive_mon_intval,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -5662,6 +5669,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
hdd_info("Name = [%s] Value = [%u]",
CFG_ADAPT_DWELL_WIFI_THRESH_NAME,
pHddCtx->config->adapt_dwell_wifi_act_threshold);
+ hdd_info("Name = [%s] value = [%u]",
+ CFG_SUB_20_CHANNEL_WIDTH_NAME,
+ pHddCtx->config->enable_sub_20_channel_width);
hdd_ndp_print_ini_config(pHddCtx);
hdd_info("Name = [%s] Value = [%s]",
CFG_RM_CAPABILITY_NAME,
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 9e04bec8a720..a0f24319c70e 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -1437,6 +1437,12 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
if (status)
goto out;
+ if (cds_is_sub_20_mhz_enabled()) {
+ hdd_err("ACS not supported in sub 20 MHz ch wd.");
+ status = -EINVAL;
+ goto out;
+ }
+
sap_config = &adapter->sessionCtx.ap.sapConfig;
qdf_mem_zero(&sap_config->acs_cfg, sizeof(struct sap_acs_cfg));
@@ -8452,6 +8458,12 @@ static int __wlan_hdd_change_station(struct wiphy *wiphy,
(pAdapter->device_mode == QDF_P2P_CLIENT_MODE)) {
#ifdef FEATURE_WLAN_TDLS
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
+
+ if (cds_is_sub_20_mhz_enabled()) {
+ hdd_err("TDLS not allowed with sub 20 MHz");
+ return -EINVAL;
+ }
+
StaParams.capability = params->capability;
StaParams.uapsd_queues = params->uapsd_queues;
StaParams.max_sp = params->max_sp;
diff --git a/core/hdd/src/wlan_hdd_ftm.c b/core/hdd/src/wlan_hdd_ftm.c
index a96090e35033..83d4cdd723b6 100644
--- a/core/hdd/src/wlan_hdd_ftm.c
+++ b/core/hdd/src/wlan_hdd_ftm.c
@@ -150,6 +150,7 @@ int hdd_update_cds_config_ftm(hdd_context_t *hdd_ctx)
* frame translation 802.11 <-> 802.3
*/
cds_cfg->frame_xln_reqd = 1;
+ cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
cds_init_ini_config(cds_cfg);
return 0;
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index f63a34d4cb29..c4bcf59df5a7 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -8371,6 +8371,39 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
channel = ieee80211_frequency_to_channel(
params->chandef.chan->center_freq);
+ if (cds_is_sub_20_mhz_enabled()) {
+ enum channel_state ch_state;
+ enum phy_ch_width sub_20_ch_width = CH_WIDTH_INVALID;
+ /* Avoid ACS/DFS, and overwrite ch wd to 20 */
+ if (channel == 0) {
+ hdd_err("Can't start SAP-ACS (channel=0) with sub 20 MHz ch width.");
+ return -EINVAL;
+ }
+ if (CHANNEL_STATE_DFS == cds_get_channel_state(channel)) {
+ hdd_err("Can't start SAP-DFS (channel=%d)with sub 20 MHz ch wd",
+ channel);
+ return -EINVAL;
+ }
+ if (channel_width != HW_MODE_20_MHZ) {
+ hdd_err("Hostapd (20+ MHz) conflits with config.ini (sub 20 MHz)");
+ return -EINVAL;
+ }
+ if (cds_is_5_mhz_enabled())
+ sub_20_ch_width = CH_WIDTH_5MHZ;
+ if (cds_is_10_mhz_enabled())
+ sub_20_ch_width = CH_WIDTH_10MHZ;
+ if (CDS_IS_CHANNEL_5GHZ(channel))
+ ch_state = cds_get_5g_bonded_channel_state(channel,
+ sub_20_ch_width);
+ else
+ ch_state = cds_get_2g_bonded_channel_state(channel,
+ sub_20_ch_width, 0);
+ if (CHANNEL_STATE_DISABLE == ch_state) {
+ hdd_err("Given ch width not supported by reg domain.");
+ return -EINVAL;
+ }
+ }
+
/* check if concurrency is allowed */
if (!cds_allow_concurrency(
cds_convert_device_mode_to_qdf_type(
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index fecba9a681e5..caf39aae25f0 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -1347,6 +1347,19 @@ void hdd_update_tgt_cfg(void *context, void *param)
hdd_context_t *hdd_ctx = (hdd_context_t *) context;
struct wma_tgt_cfg *cfg = param;
uint8_t temp_band_cap;
+ struct cds_config_info *cds_cfg = cds_get_ini_config();
+
+ if (cds_cfg) {
+ if (hdd_ctx->config->enable_sub_20_channel_width !=
+ WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
+ hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
+ cds_cfg->sub_20_channel_width =
+ WLAN_SUB_20_CH_WIDTH_NONE;
+ } else {
+ cds_cfg->sub_20_channel_width =
+ hdd_ctx->config->enable_sub_20_channel_width;
+ }
+ }
/* first store the INI band capability */
temp_band_cap = hdd_ctx->config->nBandCapability;
@@ -6518,6 +6531,7 @@ int hdd_update_cds_config(hdd_context_t *hdd_ctx)
cds_cfg->tx_chain_mask_cck = hdd_ctx->config->tx_chain_mask_cck;
cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
cds_cfg->max_station = hdd_ctx->config->maxNumberOfPeers;
+ cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c
index 8a3f06c7f6a0..e26a2e9fb5e5 100644
--- a/core/mac/src/pe/lim/lim_assoc_utils.c
+++ b/core/mac/src/pe/lim/lim_assoc_utils.c
@@ -3987,6 +3987,14 @@ tSirRetStatus lim_sta_send_add_bss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
/* we need to defer the message until we get the response back from HAL. */
SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ if (cds_is_5_mhz_enabled()) {
+ pAddBssParams->ch_width = CH_WIDTH_5MHZ;
+ pAddBssParams->staContext.ch_width = CH_WIDTH_5MHZ;
+ } else if (cds_is_10_mhz_enabled()) {
+ pAddBssParams->ch_width = CH_WIDTH_10MHZ;
+ pAddBssParams->staContext.ch_width = CH_WIDTH_10MHZ;
+ }
+
msgQ.type = WMA_ADD_BSS_REQ;
/** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
msgQ.reserved = 0;
@@ -4464,6 +4472,14 @@ tSirRetStatus lim_sta_send_add_bss_pre_assoc(tpAniSirGlobal pMac, uint8_t update
/* we need to defer the message until we get the response back from HAL. */
SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ if (cds_is_5_mhz_enabled()) {
+ pAddBssParams->ch_width = CH_WIDTH_5MHZ;
+ pAddBssParams->staContext.ch_width = CH_WIDTH_5MHZ;
+ } else if (cds_is_10_mhz_enabled()) {
+ pAddBssParams->ch_width = CH_WIDTH_10MHZ;
+ pAddBssParams->staContext.ch_width = CH_WIDTH_10MHZ;
+ }
+
msgQ.type = WMA_ADD_BSS_REQ;
/** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
msgQ.reserved = 0;
diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
index e103222c26c5..1bf4471e9f08 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
@@ -599,6 +599,14 @@ lim_mlm_add_bss(tpAniSirGlobal mac_ctx,
lim_log(mac_ctx, LOG2, FL("dot11_mode:%d nss value:%d"),
addbss_param->dot11_mode, addbss_param->nss);
+ if (cds_is_5_mhz_enabled()) {
+ addbss_param->ch_width = CH_WIDTH_5MHZ;
+ addbss_param->staContext.ch_width = CH_WIDTH_5MHZ;
+ } else if (cds_is_10_mhz_enabled()) {
+ addbss_param->ch_width = CH_WIDTH_10MHZ;
+ addbss_param->staContext.ch_width = CH_WIDTH_10MHZ;
+ }
+
msg_buf.type = WMA_ADD_BSS_REQ;
msg_buf.reserved = 0;
msg_buf.bodyptr = addbss_param;
diff --git a/core/mac/src/pe/lim/lim_send_messages.c b/core/mac/src/pe/lim/lim_send_messages.c
index 02088d335d75..8233822f0284 100644
--- a/core/mac/src/pe/lim/lim_send_messages.c
+++ b/core/mac/src/pe/lim/lim_send_messages.c
@@ -262,6 +262,11 @@ tSirRetStatus lim_send_switch_chnl_params(tpAniSirGlobal pMac,
pChnlParams->restart_on_chan_switch = is_restart;
+ if (cds_is_5_mhz_enabled())
+ pChnlParams->ch_width = CH_WIDTH_5MHZ;
+ else if (cds_is_10_mhz_enabled())
+ pChnlParams->ch_width = CH_WIDTH_10MHZ;
+
/* we need to defer the message until we
* get the response back from WMA
*/
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 4f12771139ae..9597cccebabf 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -720,11 +720,16 @@ QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
else
pChanList->chanParam[num_channel].dfsSet =
true;
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
"channel:%d, pwr=%d, DFS=%d\n",
pChanList->chanParam[num_channel].chanId,
pChanList->chanParam[num_channel].pwr,
pChanList->chanParam[num_channel].dfsSet);
+ if (cds_is_5_mhz_enabled())
+ pChanList->chanParam[num_channel].quarter_rate
+ = 1;
+ else if (cds_is_10_mhz_enabled())
+ pChanList->chanParam[num_channel].half_rate = 1;
num_channel++;
}
}
@@ -732,15 +737,20 @@ QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
if (CSR_IS_5G_BAND_ONLY(pMac)) {
for (j = 0; j < MAX_SOCIAL_CHANNELS; j++) {
if (cds_get_channel_state(social_channel[j])
- == CHANNEL_STATE_ENABLE) {
- pChanList->chanParam[num_channel].chanId =
- social_channel[j];
- pChanList->chanParam[num_channel].pwr =
- csr_find_channel_pwr(pScan->defaultPowerTable,
- social_channel[j]);
- pChanList->chanParam[num_channel].dfsSet = false;
- num_channel++;
- }
+ != CHANNEL_STATE_ENABLE)
+ continue;
+ pChanList->chanParam[num_channel].chanId =
+ social_channel[j];
+ pChanList->chanParam[num_channel].pwr =
+ csr_find_channel_pwr(pScan->defaultPowerTable,
+ social_channel[j]);
+ pChanList->chanParam[num_channel].dfsSet = false;
+ if (cds_is_5_mhz_enabled())
+ pChanList->chanParam[num_channel].quarter_rate
+ = 1;
+ else if (cds_is_10_mhz_enabled())
+ pChanList->chanParam[num_channel].half_rate = 1;
+ num_channel++;
}
}
if (pMac->roam.configParam.early_stop_scan_enable)
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index dd321034b759..3895465b921f 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -1438,6 +1438,7 @@ typedef struct {
bool nan_datapath_enabled;
QDF_STATUS (*pe_ndp_event_handler)(tpAniSirGlobal mac_ctx,
cds_msg_t *msg);
+ bool sub_20_support;
} t_wma_handle, *tp_wma_handle;
/**
diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h
index 6e9113896733..000b492b142d 100644
--- a/core/wma/inc/wma_tgt_cfg.h
+++ b/core/wma/inc/wma_tgt_cfg.h
@@ -172,5 +172,6 @@ struct wma_tgt_cfg {
#ifdef WLAN_FEATURE_NAN_DATAPATH
bool nan_datapath_enabled;
#endif
+ bool sub_20_support;
};
#endif /* WMA_TGT_CFG_H */
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index 144a08b8773c..2af766ed6a4a 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -2747,6 +2747,12 @@ static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss)
req.vdev_id = vdev_id;
req.chan = add_bss->currentOperChannel;
req.chan_width = add_bss->ch_width;
+
+ if (add_bss->ch_width == CH_WIDTH_10MHZ)
+ req.is_half_rate = 1;
+ else if (add_bss->ch_width == CH_WIDTH_5MHZ)
+ req.is_quarter_rate = 1;
+
req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
req.vht_capable = add_bss->vhtCapable;
@@ -3089,6 +3095,12 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
req.vdev_id = vdev_id;
req.chan = add_bss->currentOperChannel;
req.chan_width = add_bss->ch_width;
+
+ if (add_bss->ch_width == CH_WIDTH_10MHZ)
+ req.is_half_rate = 1;
+ else if (add_bss->ch_width == CH_WIDTH_5MHZ)
+ req.is_quarter_rate = 1;
+
req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
req.max_txpow = add_bss->maxTxPower;
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index b9f0ce6ecb20..f61b13b3011d 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -3913,6 +3913,8 @@ static void wma_update_hdd_cfg(tp_wma_handle wma_handle)
void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
qdf_mem_zero(&tgt_cfg, sizeof(struct wma_tgt_cfg));
+
+ tgt_cfg.sub_20_support = wma_handle->sub_20_support;
tgt_cfg.reg_domain = wma_handle->reg_cap.eeprom_rd;
tgt_cfg.eeprom_rd_ext = wma_handle->reg_cap.eeprom_rd_ext;
@@ -4771,6 +4773,9 @@ int wma_rx_ready_event(void *handle, uint8_t *cmd_param_info,
ev = param_buf->fixed_param;
/* Indicate to the waiting thread that the ready
* event was received */
+ wma_handle->sub_20_support =
+ WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+ WMI_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT);
wma_handle->wmi_ready = true;
wma_handle->wlan_init_status = ev->status;
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index ea2dd675d02e..6af4604dad3b 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -2798,6 +2798,12 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
}
req.chan = params->channelNumber;
req.chan_width = params->ch_width;
+
+ if (params->ch_width == CH_WIDTH_10MHZ)
+ req.is_half_rate = 1;
+ else if (params->ch_width == CH_WIDTH_5MHZ)
+ req.is_quarter_rate = 1;
+
req.vht_capable = params->vhtCapable;
req.ch_center_freq_seg0 = params->ch_center_freq_seg0;
req.ch_center_freq_seg1 = params->ch_center_freq_seg1;