diff options
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 229 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 62 |
2 files changed, 162 insertions, 129 deletions
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 12aa210ccdd3..73b984cc678d 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -19143,6 +19143,129 @@ void hdd_update_beacon_rate(hdd_adapter_t *pAdapter, struct wiphy *wiphy, #if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0)) || defined(WITH_BACKPORTS) +static int hdd_config_sub20_channel(hdd_context_t *pHddCtx, uint8_t channel, + uint32_t channel_width) +{ + bool channel_support_sub20 = true; + tSmeConfigParams *sme_config; + uint8_t sub20_config; + uint8_t sub20_dyn_channelwidth = 0; + uint8_t sub20_static_channelwidth = 0; + uint8_t sub20_channelwidth = 0; + enum phy_ch_width phy_sub20_channel_width = CH_WIDTH_INVALID; + + sme_config = vos_mem_malloc(sizeof(tSmeConfigParams)); + if (!sme_config) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Can't alloc mem for sme config")); + return -EINVAL; + } + vos_mem_zero(sme_config, sizeof(tSmeConfigParams)); + + sme_GetConfigParam(pHddCtx->hHal, sme_config); + sub20_config = sme_config->sub20_config_info; + + switch (sub20_config) { + case CFG_SUB_20_CHANNEL_WIDTH_5MHZ: + sub20_static_channelwidth = SUB20_MODE_5MHZ; + break; + case CFG_SUB_20_CHANNEL_WIDTH_10MHZ: + sub20_static_channelwidth = SUB20_MODE_10MHZ; + break; + case CFG_SUB_20_CHANNEL_WIDTH_DYN_5MHZ: + sub20_dyn_channelwidth = SUB20_MODE_5MHZ; + break; + case CFG_SUB_20_CHANNEL_WIDTH_DYN_10MHZ: + sub20_dyn_channelwidth = SUB20_MODE_10MHZ; + break; + case CFG_SUB_20_CHANNEL_WIDTH_DYN_ALL: + sub20_dyn_channelwidth = SUB20_MODE_5MHZ | SUB20_MODE_10MHZ; + break; + default: + break; + } + + if (channel == 0) { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("Can't start SAP-ACS with sub20 channel width")); + vos_mem_free(sme_config); + return -EINVAL; + } + + if (CSR_IS_CHANNEL_DFS(channel)) { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("Can't start SAP-DFS with sub20 channel width")); + vos_mem_free(sme_config); + return -EINVAL; + } + + if (channel_width != NL80211_CHAN_WIDTH_20 && + channel_width != NL80211_CHAN_WIDTH_20_NOHT) { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("Hostapd (20+MHz) conflicts config.ini(sub20)")); + vos_mem_free(sme_config); + return -EINVAL; + } + + switch (sub20_config) { + case CFG_SUB_20_CHANNEL_WIDTH_5MHZ: + case CFG_SUB_20_CHANNEL_WIDTH_10MHZ: + case CFG_SUB_20_CHANNEL_WIDTH_DYN_5MHZ: + case CFG_SUB_20_CHANNEL_WIDTH_DYN_10MHZ: + sub20_channelwidth = (sub20_static_channelwidth != 0) ? + sub20_static_channelwidth : sub20_dyn_channelwidth; + phy_sub20_channel_width = + (sub20_channelwidth == SUB20_MODE_5MHZ) ? + CH_WIDTH_5MHZ : CH_WIDTH_10MHZ; + channel_support_sub20 = + vos_is_channel_support_sub20(channel, + phy_sub20_channel_width, + 0); + if (!channel_support_sub20) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("ch%dwidth%d unsupport by reg domain"), + channel, phy_sub20_channel_width); + vos_mem_free(sme_config); + return -EINVAL; + } + break; + case CFG_SUB_20_CHANNEL_WIDTH_DYN_ALL: + channel_support_sub20 = + vos_is_channel_support_sub20(channel, + CH_WIDTH_5MHZ, 0); + if (!channel_support_sub20) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("ch%dwidth5M unsupport by reg domain"), + channel); + sub20_dyn_channelwidth &= ~SUB20_MODE_5MHZ; + } + + channel_support_sub20 = + vos_is_channel_support_sub20(channel, + CH_WIDTH_10MHZ, 0); + if (!channel_support_sub20) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("ch%dwidth10M unsupport by reg domain"), + channel); + sub20_dyn_channelwidth &= ~SUB20_MODE_10MHZ; + } + + if (sub20_dyn_channelwidth == 0) { + vos_mem_free(sme_config); + return -EINVAL; + } else { + sme_config->sub20_dynamic_channelwidth = + sub20_dyn_channelwidth; + sme_UpdateConfig(pHddCtx->hHal, sme_config); + } + break; + default: + break; + } + vos_mem_free(sme_config); + return 0; +} + static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *params) @@ -19152,6 +19275,7 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, uint32_t channel_width; hdd_context_t *pHddCtx; int status; + int ret = 0; ENTER(); clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags); @@ -19193,108 +19317,9 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, /* Avoid ACS/DFS, and overwrite channel width to 20 */ if (hdd_cfg_is_sub20_channel_width_enabled(pHddCtx)) { - bool channel_support_sub20 = true; - tSmeConfigParams sme_config; - uint8_t sub20_config; - uint8_t sub20_dyn_channelwidth = 0; - uint8_t sub20_static_channelwidth = 0; - uint8_t sub20_channelwidth = 0; - enum phy_ch_width phy_sub20_channel_width = CH_WIDTH_INVALID; - - vos_mem_zero(&sme_config, sizeof(sme_config)); - sme_GetConfigParam(pHddCtx->hHal, &sme_config); - sub20_config = sme_config.sub20_config_info; - - switch (sub20_config) { - case CFG_SUB_20_CHANNEL_WIDTH_5MHZ: - sub20_static_channelwidth = SUB20_MODE_5MHZ; - break; - case CFG_SUB_20_CHANNEL_WIDTH_10MHZ: - sub20_static_channelwidth = SUB20_MODE_10MHZ; - break; - case CFG_SUB_20_CHANNEL_WIDTH_DYN_5MHZ: - sub20_dyn_channelwidth = SUB20_MODE_5MHZ; - break; - case CFG_SUB_20_CHANNEL_WIDTH_DYN_10MHZ: - sub20_dyn_channelwidth = SUB20_MODE_10MHZ; - break; - case CFG_SUB_20_CHANNEL_WIDTH_DYN_ALL: - sub20_dyn_channelwidth = SUB20_MODE_5MHZ | SUB20_MODE_10MHZ; - break; - default: - break; - } - - if (channel == 0) { - hddLog(VOS_TRACE_LEVEL_WARN, - FL("Can't start SAP-ACS with sub20 channel width")); - return -EINVAL; - } - - if (CSR_IS_CHANNEL_DFS(channel)) { - hddLog(VOS_TRACE_LEVEL_WARN, - FL("Can't start SAP-DFS with sub20 channel width")); - return -EINVAL; - } - - if (channel_width != NL80211_CHAN_WIDTH_20 && - channel_width != NL80211_CHAN_WIDTH_20_NOHT) { - hddLog(VOS_TRACE_LEVEL_WARN, - FL("Hostapd (20+MHz) conflicts config.ini(sub20)")); - return -EINVAL; - } - - switch (sub20_config) { - case CFG_SUB_20_CHANNEL_WIDTH_5MHZ: - case CFG_SUB_20_CHANNEL_WIDTH_10MHZ: - case CFG_SUB_20_CHANNEL_WIDTH_DYN_5MHZ: - case CFG_SUB_20_CHANNEL_WIDTH_DYN_10MHZ: - sub20_channelwidth = (sub20_static_channelwidth != 0) ? - sub20_static_channelwidth : sub20_dyn_channelwidth; - phy_sub20_channel_width = - (sub20_channelwidth == SUB20_MODE_5MHZ) ? - CH_WIDTH_5MHZ : CH_WIDTH_10MHZ; - channel_support_sub20 = - vos_is_channel_support_sub20(channel, - phy_sub20_channel_width, - 0); - if (!channel_support_sub20) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("ch%dwidth%d unsupport by reg domain"), - channel, phy_sub20_channel_width); - return -EINVAL; - } - break; - case CFG_SUB_20_CHANNEL_WIDTH_DYN_ALL: - channel_support_sub20 = - vos_is_channel_support_sub20(channel, CH_WIDTH_5MHZ, 0); - if (!channel_support_sub20) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("ch%dwidth5M unsupport by reg domain"), - channel); - sub20_dyn_channelwidth &= ~SUB20_MODE_5MHZ; - } - - channel_support_sub20 = - vos_is_channel_support_sub20(channel, CH_WIDTH_10MHZ, 0); - if (!channel_support_sub20) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("ch%dwidth10M unsupport by reg domain"), - channel); - sub20_dyn_channelwidth &= ~SUB20_MODE_10MHZ; - } - - if (sub20_dyn_channelwidth == 0) { - return -EINVAL; - } else { - sme_config.sub20_dynamic_channelwidth = - sub20_dyn_channelwidth; - sme_UpdateConfig(pHddCtx->hHal, &sme_config); - } - break; - default: - break; - } + ret = hdd_config_sub20_channel(pHddCtx, channel, channel_width); + if (ret) + return ret; } if (pAdapter->device_mode == WLAN_HDD_P2P_GO) { diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 2f9cd31e2185..675763dfc6ef 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -13055,7 +13055,7 @@ eIniChanBondState sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode, uint16_t *vht_channel_width, uint16_t ch_width_orig) { - tSmeConfigParams smeConfig; + tSmeConfigParams *smeConfig; tANI_U32 ht40plus2gendch = 0; tpAniSirGlobal pMac = PMAC_STRUCT(hHal); eIniChanBondState cb_mode = eCSR_INI_SINGLE_CHANNEL_CENTERED; @@ -13066,53 +13066,60 @@ eIniChanBondState sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode, "%s: HW: %d CH: %d ORIG_BW: %d\n", __func__, eCsrPhyMode, channel, ch_width_orig); + smeConfig = vos_mem_malloc(sizeof(tSmeConfigParams)); + if (!smeConfig) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Can't alloc mem for sme config")); + return -EINVAL; + } + *vht_channel_width = ch_width_orig; - vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams)); - sme_GetConfigParam(pMac, &smeConfig); + vos_mem_zero(smeConfig, sizeof (tSmeConfigParams)); + sme_GetConfigParam(pMac, smeConfig); if ((eCSR_DOT11_MODE_11ac == eCsrPhyMode || eCSR_DOT11_MODE_11ac_ONLY == eCsrPhyMode) && (eHT_CHANNEL_WIDTH_80MHZ == ch_width_orig)) { if (channel== 36 || channel == 52 || channel == 100 || channel == 116 || channel == 149 || channel == 132) { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; } else if (channel == 40 || channel == 56 || channel == 104 || channel == 120 || channel == 153 || channel == 136) { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; } else if (channel == 44 || channel == 60 || channel == 108 || channel == 124 || channel == 157 || channel == 140) { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; } else if (channel == 48 || channel == 64 || channel == 112 || channel == 128 || channel == 144 || channel == 161) { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; } else if (channel == 165) { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_SINGLE_CHANNEL_CENTERED; *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ; } else if (channel >= 1 && channel < 5) { - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; *vht_channel_width = eHT_CHANNEL_WIDTH_40MHZ; } else if (channel >= 5 && channel <= 9) { if (0 != ht_sec_ch) { if (ht_sec_ch > channel) - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; else - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; } *vht_channel_width = eHT_CHANNEL_WIDTH_40MHZ; } else if (channel > 9 && channel <= 13) { - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; *vht_channel_width = eHT_CHANNEL_WIDTH_40MHZ; } else if (channel ==14) { - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_SINGLE_CHANNEL_CENTERED; *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ; } @@ -13129,55 +13136,56 @@ eIniChanBondState sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode, channel == 64 || channel == 104 || channel == 112 || channel == 120 || channel == 128 || channel == 136 || channel == 153 || channel == 161 || channel == 144) { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; } else if (channel== 36 || channel == 44 || channel == 52 || channel == 60 || channel == 100 || channel == 108 || channel == 116 || channel == 124 || channel == 132 || channel == 149 || channel == 157 || channel == 140) { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; } else if (channel == 165) { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_SINGLE_CHANNEL_CENTERED; *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ; } else if (channel >= 1 && channel < 5) { - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; } else if (channel >= 5 && channel <= ht40plus2gendch) { if (ht_sec_ch > channel) - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; else - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; } else if (channel > ht40plus2gendch && channel <= 13) { - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; } else if (channel ==14) { - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_SINGLE_CHANNEL_CENTERED; *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ; } } else { *vht_channel_width = eHT_CHANNEL_WIDTH_20MHZ; if (channel <= 14) { - smeConfig.csrConfig.channelBondingMode24GHz = + smeConfig->csrConfig.channelBondingMode24GHz = eCSR_INI_SINGLE_CHANNEL_CENTERED; } else { - smeConfig.csrConfig.channelBondingMode5GHz = + smeConfig->csrConfig.channelBondingMode5GHz = eCSR_INI_SINGLE_CHANNEL_CENTERED; } } - sme_AdjustCBMode(pMac, &smeConfig, channel, vht_channel_width); - sme_UpdateConfig (pMac, &smeConfig); - cb_mode = (channel <= 14) ? smeConfig.csrConfig.channelBondingMode24GHz : - smeConfig.csrConfig.channelBondingMode5GHz; + sme_AdjustCBMode(pMac, smeConfig, channel, vht_channel_width); + sme_UpdateConfig (pMac, smeConfig); + cb_mode = (channel <= 14) ? smeConfig->csrConfig.channelBondingMode24GHz : + smeConfig->csrConfig.channelBondingMode5GHz; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, "%s: CH: %d NEW_BW: %d %s-CB_Mode:%d", __func__, channel, *vht_channel_width, (channel <=14) ? "2G" : "5G", cb_mode); + vos_mem_free(smeConfig); return cb_mode; } |
