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
This commit is contained in:
Naveen Rawat 2016-05-20 10:34:56 -07:00 • committed by Vishwajith Upendra
commit 64e477ea40
19 changed files with 242 additions and 11 deletions

View file

@ -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 */

View file

@ -40,6 +40,17 @@ enum driver_type {
DRIVER_TYPE_MFG = 1,
};
/**
* 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
@ -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 ) */

View file

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

View file

@ -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);

View file

@ -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))

View file

@ -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,

View file

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

View file

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

View file

@ -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(

View file

@ -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);

View file

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

View file

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

View file

@ -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
*/

View file

@ -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)

View file

@ -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;
/**

View file

@ -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 */

View file

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

View file

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

View file

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