diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index 06082d60d8af..c6c792f89271 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -2483,6 +2483,7 @@ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, return; } if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) { + ch_params.ch_width = ch_width; status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params( psoc, vdev_id, ch_freq, &ch_params); if (QDF_IS_STATUS_SUCCESS(status) && diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index af5ecbbfc22c..194d901c7f1c 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1105,6 +1105,7 @@ static void __wlan_hdd_sap_pre_cac_success(struct hdd_adapter *adapter) struct hdd_adapter *ap_adapter; int i; struct hdd_context *hdd_ctx; + enum phy_ch_width pre_cac_ch_width; hdd_enter(); @@ -1114,6 +1115,9 @@ static void __wlan_hdd_sap_pre_cac_success(struct hdd_adapter *adapter) return; } + pre_cac_ch_width = wlansap_get_chan_width( + WLAN_HDD_GET_SAP_CTX_PTR(adapter)); + hdd_stop_adapter(hdd_ctx, adapter); /* Prepare to switch AP from 2.4GHz channel to the pre CAC channel */ @@ -1133,7 +1137,7 @@ static void __wlan_hdd_sap_pre_cac_success(struct hdd_adapter *adapter) CSA_REASON_PRE_CAC_SUCCESS); i = hdd_softap_set_channel_change(ap_adapter->dev, ap_adapter->pre_cac_freq, - CH_WIDTH_MAX, false); + pre_cac_ch_width, false); if (0 != i) { hdd_err("failed to change channel"); wlan_hdd_set_pre_cac_complete_status(ap_adapter, false); diff --git a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c index 89bbd1a7cb56..7eb6d637e1e1 100644 --- a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c +++ b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c @@ -33,6 +33,9 @@ #include #include +/* default pre cac channel bandwidth */ +#define DEFAULT_PRE_CAC_BANDWIDTH CH_WIDTH_80MHZ + /** * wlan_hdd_set_pre_cac_status() - Set the pre cac status * @pre_cac_adapter: AP adapter used for pre cac @@ -152,6 +155,67 @@ static int wlan_hdd_validate_and_get_pre_cac_ch(struct hdd_context *hdd_ctx, return 0; } +static int wlan_set_def_pre_cac_chan(struct hdd_context *hdd_ctx, + uint32_t pre_cac_ch_freq, + struct cfg80211_chan_def *chandef, + enum nl80211_channel_type *chantype, + enum phy_ch_width *ch_width) +{ + enum nl80211_channel_type channel_type; + struct ieee80211_channel *ieee_chan; + struct ch_params ch_params = {0}; + + ieee_chan = ieee80211_get_channel(hdd_ctx->wiphy, + pre_cac_ch_freq); + if (!ieee_chan) { + hdd_err("channel converion failed %d", pre_cac_ch_freq); + return -EINVAL; + } + ch_params.ch_width = *ch_width; + wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, + pre_cac_ch_freq, 0, + &ch_params); + switch (ch_params.sec_ch_offset) { + case HIGH_PRIMARY_CH: + channel_type = NL80211_CHAN_HT40MINUS; + break; + case LOW_PRIMARY_CH: + channel_type = NL80211_CHAN_HT40PLUS; + break; + default: + channel_type = NL80211_CHAN_HT20; + break; + } + cfg80211_chandef_create(chandef, ieee_chan, channel_type); + switch (ch_params.ch_width) { + case CH_WIDTH_80MHZ: + chandef->width = NL80211_CHAN_WIDTH_80; + break; + case CH_WIDTH_80P80MHZ: + chandef->width = NL80211_CHAN_WIDTH_80P80; + if (ch_params.mhz_freq_seg1) + chandef->center_freq2 = ch_params.mhz_freq_seg1; + break; + case CH_WIDTH_160MHZ: + chandef->width = NL80211_CHAN_WIDTH_160; + break; + default: + break; + } + if (ch_params.ch_width == CH_WIDTH_80MHZ || + ch_params.ch_width == CH_WIDTH_80P80MHZ || + ch_params.ch_width == CH_WIDTH_160MHZ) { + if (ch_params.mhz_freq_seg0) + chandef->center_freq1 = ch_params.mhz_freq_seg0; + } + *chantype = channel_type; + *ch_width = ch_params.ch_width; + hdd_debug("pre cac ch def: chan:%d width:%d freq1:%d freq2:%d", + chandef->chan->center_freq, chandef->width, + chandef->center_freq1, chandef->center_freq2); + + return 0; +} /** * __wlan_hdd_request_pre_cac() - Start pre CAC in the driver * @hdd_ctx: the HDD context to operate against @@ -177,9 +241,9 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, struct net_device *dev; struct cfg80211_chan_def chandef; enum nl80211_channel_type channel_type; - struct ieee80211_channel *chan; mac_handle_t mac_handle; bool val; + enum phy_ch_width cac_ch_width; if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) { hdd_debug("Pre CAC is not supported on non-dbs platforms"); @@ -318,36 +382,30 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, pre_cac_adapter->session.ap.sap_config.authType = ap_adapter->session.ap.sap_config.authType; - /* Premise is that on moving from 2.4GHz to 5GHz, the SAP will continue - * to operate on the same bandwidth as that of the 2.4GHz operations. - * Only bandwidths 20MHz/40MHz are possible on 2.4GHz band. + /* The orginal premise is that on moving from 2.4GHz to 5GHz, the SAP + * will continue to operate on the same bandwidth as that of the 2.4GHz + * operations. Only bandwidths 20MHz/40MHz are possible on 2.4GHz band. + * Now some customer request to start AP on higher BW such as 80Mhz. + * Hence use max possible supported BW based on phymode configurated + * on SAP. */ - switch (ap_adapter->session.ap.sap_config.ch_width_orig) { - case CH_WIDTH_20MHZ: - channel_type = NL80211_CHAN_HT20; - break; - case CH_WIDTH_40MHZ: - if (ap_adapter->session.ap.sap_config.sec_ch_freq > - ap_adapter->session.ap.sap_config.chan_freq) - channel_type = NL80211_CHAN_HT40PLUS; - else - channel_type = NL80211_CHAN_HT40MINUS; - break; - default: - channel_type = NL80211_CHAN_NO_HT; - break; - } + cac_ch_width = wlansap_get_max_bw_by_phymode( + WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter)); + if (cac_ch_width > DEFAULT_PRE_CAC_BANDWIDTH) + cac_ch_width = DEFAULT_PRE_CAC_BANDWIDTH; - chan = ieee80211_get_channel(wiphy, pre_cac_chan_freq); - if (!chan) { - hdd_err("channel converion failed"); - goto stop_close_pre_cac_adapter; + qdf_mem_zero(&chandef, sizeof(struct cfg80211_chan_def)); + if (wlan_set_def_pre_cac_chan(hdd_ctx, pre_cac_chan_freq, + &chandef, &channel_type, + &cac_ch_width)) { + hdd_err("error set pre_cac channel %d", pre_cac_chan_freq); + goto close_pre_cac_adapter; } - cfg80211_chandef_create(&chandef, chan, channel_type); + pre_cac_adapter->session.ap.sap_config.ch_width_orig = chandef.width; - hdd_debug("orig width:%d channel_type:%d freq:%d", - ap_adapter->session.ap.sap_config.ch_width_orig, - channel_type, pre_cac_chan_freq); + hdd_debug("existing ap phymode:%d pre cac ch_width:%d freq:%d", + ap_adapter->session.ap.sap_config.SapHw_mode, + cac_ch_width, pre_cac_chan_freq); /* * Doing update after opening and starting pre-cac adapter will make * sure that driver won't do hardware mode change if there are any diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 851433702958..dc6cef2c72e2 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -1420,6 +1420,17 @@ void sap_undo_acs(struct sap_context *sap_context, struct sap_config *sap_cfg); */ uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx); +/** + * wlansap_get_max_bw_by_phymode() - get max channel width based on phymode + * @sap_ctx: pointer to the SAP context + * + * This function get max channel width of sap based on phymode. + * + * Return: channel width + */ +enum phy_ch_width +wlansap_get_max_bw_by_phymode(struct sap_context *sap_ctx); + /* * wlansap_set_invalid_session() - set session ID to invalid * @sap_ctx: pointer to the SAP context diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 8d630762f0d1..8dc13d48f230 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -1231,7 +1231,6 @@ wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context, uint32_t chan_freq, struct ch_params *tgt_ch_params) { - uint32_t max_fw_bw; enum phy_ch_width ch_width, concurrent_bw = 0; struct mac_context *mac = sap_get_mac_context(); struct ch_params ch_params = {0}; @@ -1244,32 +1243,13 @@ wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context, */ ch_width = CH_WIDTH_20MHZ; } else { - if (sap_context->csr_roamProfile.phyMode == - eCSR_DOT11_MODE_11ac || - sap_context->csr_roamProfile.phyMode == - eCSR_DOT11_MODE_11ac_ONLY || - sap_context->csr_roamProfile.phyMode == - eCSR_DOT11_MODE_11ax || - sap_context->csr_roamProfile.phyMode == - eCSR_DOT11_MODE_11ax_ONLY) { - max_fw_bw = sme_get_vht_ch_width(); - if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) - ch_width = CH_WIDTH_160MHZ; - else - ch_width = CH_WIDTH_80MHZ; - } else if (sap_context->csr_roamProfile.phyMode == - eCSR_DOT11_MODE_11n || - sap_context->csr_roamProfile.phyMode == - eCSR_DOT11_MODE_11n_ONLY) { - ch_width = CH_WIDTH_40MHZ; - } else { - /* For legacy 11a mode return 20MHz */ - ch_width = CH_WIDTH_20MHZ; - } + ch_width = wlansap_get_max_bw_by_phymode(sap_context); concurrent_bw = wlan_sap_get_concurrent_bw( mac->pdev, mac->psoc, chan_freq, ch_width); ch_width = QDF_MIN(ch_width, concurrent_bw); + if (tgt_ch_params) + ch_width = QDF_MIN(ch_width, tgt_ch_params->ch_width); } ch_params.ch_width = ch_width; wlan_reg_set_channel_params_for_freq(mac->pdev, chan_freq, 0, @@ -1277,11 +1257,11 @@ wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context, ch_width = ch_params.ch_width; if (tgt_ch_params) *tgt_ch_params = ch_params; - sap_nofl_debug("freq %d bw %d (orig bw %d phymode %d, con bw %d)", + sap_nofl_debug("freq %d bw %d (phymode %d, con bw %d, tgt bw %d)", chan_freq, ch_width, - sap_context->ch_width_orig, sap_context->csr_roamProfile.phyMode, - concurrent_bw); + concurrent_bw, + tgt_ch_params ? tgt_ch_params->ch_width : CH_WIDTH_MAX); return ch_width; } @@ -1355,10 +1335,13 @@ wlansap_set_chan_params_for_csa(struct mac_context *mac, uint32_t target_chan_freq, enum phy_ch_width target_bw) { + struct ch_params tmp_ch_params = {0}; + + tmp_ch_params.ch_width = target_bw; mac->sap.SapDfsInfo.new_chanWidth = wlansap_get_csa_chanwidth_from_phymode(sap_ctx, target_chan_freq, - NULL); + &tmp_ch_params); /* * Copy the requested target channel * to sap context. @@ -1448,10 +1431,10 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(mac->psoc); - tmp_ch_params.ch_width = - wlansap_get_csa_chanwidth_from_phymode(sap_ctx, - target_chan_freq, - NULL); + tmp_ch_params.ch_width = target_bw; + wlansap_get_csa_chanwidth_from_phymode(sap_ctx, + target_chan_freq, + &tmp_ch_params); if (target_bw != CH_WIDTH_MAX) { tmp_ch_params.ch_width = QDF_MIN(tmp_ch_params.ch_width, target_bw); @@ -2608,6 +2591,43 @@ uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx) return wlan_sap_get_vht_ch_width(sap_ctx); } +enum phy_ch_width +wlansap_get_max_bw_by_phymode(struct sap_context *sap_ctx) +{ + uint32_t max_fw_bw; + enum phy_ch_width ch_width; + + if (!sap_ctx) { + sap_err("Invalid SAP pointer"); + return CH_WIDTH_20MHZ; + } + + if (sap_ctx->csr_roamProfile.phyMode == + eCSR_DOT11_MODE_11ac || + sap_ctx->csr_roamProfile.phyMode == + eCSR_DOT11_MODE_11ac_ONLY || + sap_ctx->csr_roamProfile.phyMode == + eCSR_DOT11_MODE_11ax || + sap_ctx->csr_roamProfile.phyMode == + eCSR_DOT11_MODE_11ax_ONLY) { + max_fw_bw = sme_get_vht_ch_width(); + if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) + ch_width = CH_WIDTH_160MHZ; + else + ch_width = CH_WIDTH_80MHZ; + } else if (sap_ctx->csr_roamProfile.phyMode == + eCSR_DOT11_MODE_11n || + sap_ctx->csr_roamProfile.phyMode == + eCSR_DOT11_MODE_11n_ONLY) { + ch_width = CH_WIDTH_40MHZ; + } else { + /* For legacy 11a mode return 20MHz */ + ch_width = CH_WIDTH_20MHZ; + } + + return ch_width; +} + QDF_STATUS wlansap_set_invalid_session(struct sap_context *sap_ctx) { if (!sap_ctx) {