From 3b174b735582b2a5aa840017b9f0cf0ad77586dc Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 31 Mar 2023 17:32:09 +0800 Subject: [PATCH] qcacld-3.0: Optimization of SAP bw selection in LTE coex event Add optimization to select the max possible band width when do SAP LTE channel avoidance channel change. Change-Id: I82745d47c55ae42f59691a9634a34b0cff2b4e36 CRs-Fixed: 3440166 --- core/hdd/inc/wlan_hdd_main.h | 5 +- core/hdd/src/wlan_hdd_main.c | 23 +++-- core/hdd/src/wlan_hdd_regulatory.c | 2 +- core/sap/inc/sap_api.h | 4 +- core/sap/src/sap_fsm.c | 3 +- core/sap/src/sap_module.c | 154 +++++++++++++++++++++++++++-- 6 files changed, 172 insertions(+), 19 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 28b29c8df9..a1ca4cc342 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -3190,6 +3190,7 @@ void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel, * hdd_switch_sap_chan_freq() - Move SAP to the given channel * @adapter: AP adapter * @chan_freq: Channel frequency + * @ch_width: channel bandwidth * @forced: Force to switch channel, ignore SCC/MCC check * * Moves the SAP interface by invoking the function which @@ -3198,7 +3199,9 @@ void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel, * Return: QDF_STATUS_SUCCESS if successfully */ QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter, - qdf_freq_t chan_freq, bool forced); + qdf_freq_t chan_freq, + enum phy_ch_width ch_width, + bool forced); #if defined(FEATURE_WLAN_CH_AVOID) void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 9fdd2edb78..95fa3c7356 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -11671,7 +11671,9 @@ void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel, } QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter, - qdf_freq_t chan_freq, bool forced) + qdf_freq_t chan_freq, + enum phy_ch_width ch_width, + bool forced) { struct hdd_ap_ctx *hdd_ap_ctx; struct hdd_context *hdd_ctx; @@ -11686,13 +11688,13 @@ QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter, hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter); - hdd_debug("chan freq:%d width:%d", - chan_freq, hdd_ap_ctx->sap_config.ch_width_orig); + hdd_debug("chan freq:%d width:%d org bw %d", + chan_freq, ch_width, hdd_ap_ctx->sap_config.ch_width_orig); return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, adapter->deflink->vdev_id, chan_freq, - hdd_ap_ctx->sap_config.ch_width_orig, + ch_width, forced); } @@ -11846,6 +11848,7 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) bool is_vendor_acs_support = cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION); wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP; + enum phy_ch_width ch_width; hdd_for_each_adapter_dev_held_safe(hdd_ctxt, adapter, next_adapter, dbgid) { @@ -11860,7 +11863,7 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) } ap_chan_freq = ap_ctx->operating_chan_freq; - + ch_width = ap_ctx->sap_config.ch_width_orig; found = false; status = ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctxt->psoc, @@ -11924,7 +11927,8 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) if (!restart_freq) { restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); + WLAN_HDD_GET_SAP_CTX_PTR(adapter), + &ch_width); } if (!restart_freq) { wlan_hdd_set_sap_csa_reason(hdd_ctxt->psoc, @@ -11952,6 +11956,7 @@ void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt) CSA_REASON_UNSAFE_CHANNEL); status = hdd_switch_sap_chan_freq(adapter, restart_freq, + ch_width, true); if (QDF_IS_STATUS_SUCCESS(status)) { hdd_adapter_dev_put_debug(adapter, dbgid); @@ -12037,7 +12042,8 @@ static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, uint32_t restart_freq; restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( - WLAN_HDD_GET_SAP_CTX_PTR(adapter)); + WLAN_HDD_GET_SAP_CTX_PTR(adapter), + NULL); restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, restart_freq); @@ -19525,7 +19531,8 @@ void hdd_check_and_restart_sap_with_non_dfs_acs(void) restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( - WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter)); + WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), + NULL); restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, restart_freq); diff --git a/core/hdd/src/wlan_hdd_regulatory.c b/core/hdd/src/wlan_hdd_regulatory.c index 1b8a3fbae7..d6469120bb 100644 --- a/core/hdd/src/wlan_hdd_regulatory.c +++ b/core/hdd/src/wlan_hdd_regulatory.c @@ -1740,7 +1740,7 @@ static void hdd_restart_sap_with_new_phymode(struct hdd_context *hdd_ctx, } sap_config->chan_freq = - wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx); + wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx, NULL); sap_config->sap_orig_hw_mode = sap_config->SapHw_mode; sap_config->SapHw_mode = csr_phy_mode; diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 8037217f04..924e4deef8 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -1548,6 +1548,7 @@ bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx); * wlansap_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP * restart * @sap_ctx: sap context + * @ch_width: selected channel bandwdith * * Get a safe channel to restart SAP. PCL already takes into account the * unsafe channels. So, the PCL is validated with the ACS range to provide @@ -1557,7 +1558,8 @@ bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx); * failure, the channel number returned is zero. */ uint32_t -wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx); +wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx, + enum phy_ch_width *ch_width); /** * wlansap_get_safe_channel_from_pcl_for_sap() - Get safe and active channel diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 11e3e269ae..326e2752c9 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -3658,7 +3658,8 @@ static qdf_freq_t sap_get_safe_channel_freq(struct sap_context *sap_ctx) freq = wlan_pre_cac_get_freq_before_pre_cac(sap_ctx->vdev); if (!freq) freq = wlansap_get_safe_channel_from_pcl_and_acs_range( - sap_ctx); + sap_ctx, + NULL); sap_debug("new selected freq %d as target chan as current freq unsafe %d", freq, sap_ctx->chan_freq); diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index a0bb717445..41bef85c98 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -3302,9 +3302,133 @@ bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx) } #if defined(FEATURE_WLAN_CH_AVOID) +/** + * wlansap_select_chan_with_best_bandwidth() - Select channel with + * max possible band width + * @sap_ctx: sap context + * @ch_freq_list: candidate channel frequency list + * @ch_cnt: count of channel frequency in list + * @selected_freq: selected channel frequency + * @selected_ch_width: selected channel width + * + * Return: QDF_STATUS_SUCCESS if better channel selected + */ +static QDF_STATUS +wlansap_select_chan_with_best_bandwidth(struct sap_context *sap_ctx, + uint32_t *ch_freq_list, + uint32_t ch_cnt, + uint32_t *selected_freq, + enum phy_ch_width *selected_ch_width) +{ + struct mac_context *mac; + struct ch_params ch_params; + enum phy_ch_width ch_width; + uint32_t center_freq, bw_val, bw_start, bw_end; + uint16_t i, j; + uint16_t unsafe_chan[NUM_CHANNELS]; + uint16_t unsafe_chan_cnt = 0; + qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + + if (!selected_ch_width || !selected_freq) + return QDF_STATUS_E_INVAL; + + if (!qdf_ctx) { + sap_err("invalid qdf_ctx"); + return QDF_STATUS_E_INVAL; + } + + if (!sap_ctx) { + sap_err("invalid sap_ctx"); + return QDF_STATUS_E_INVAL; + } + + mac = sap_get_mac_context(); + if (!mac) { + sap_err("Invalid MAC context"); + return QDF_STATUS_E_INVAL; + } + + if (policy_mgr_get_connection_count(mac->psoc) != 1) + return QDF_STATUS_E_INVAL; + + pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan, + &unsafe_chan_cnt, + sizeof(uint16_t) * NUM_CHANNELS); + unsafe_chan_cnt = QDF_MIN(unsafe_chan_cnt, NUM_CHANNELS); + if (!unsafe_chan_cnt) + return QDF_STATUS_E_INVAL; + + ch_width = sap_ctx->ch_width_orig; +next_lower_bw: + for (i = 0; i < ch_cnt; i++) { + if (!WLAN_REG_IS_SAME_BAND_FREQS(sap_ctx->chan_freq, + ch_freq_list[i])) + continue; + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i]) && + !WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(ch_freq_list[i])) + continue; + qdf_mem_zero(&ch_params, sizeof(ch_params)); + ch_params.ch_width = ch_width; + wlan_reg_set_channel_params_for_pwrmode(mac->pdev, + ch_freq_list[i], + 0, &ch_params, + REG_CURRENT_PWR_MODE); + if (!WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i]) && + wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac->pdev, + ch_freq_list[i], + &ch_params, + REG_CURRENT_PWR_MODE) != + CHANNEL_STATE_ENABLE) + continue; + + bw_val = wlan_reg_get_bw_value(ch_params.ch_width); + if (!ch_params.mhz_freq_seg0) + continue; + if (bw_val < wlan_reg_get_bw_value(ch_width)) + continue; + if (ch_params.mhz_freq_seg1) + center_freq = ch_params.mhz_freq_seg1; + else + center_freq = ch_params.mhz_freq_seg0; + + bw_start = center_freq - bw_val / 2 + 10; + bw_end = center_freq + bw_val / 2 - 10; + for (j = 0; j < unsafe_chan_cnt; j++) + if (unsafe_chan[j] >= bw_start && + unsafe_chan[j] <= bw_end) + break; + + if (j < unsafe_chan_cnt) { + sap_debug("ch_freq %d bw %d bw start %d, bw end %d unsafe %d", + ch_freq_list[i], bw_val, bw_start, bw_end, + unsafe_chan[j]); + continue; + } + sap_debug("ch_freq %d bw %d bw start %d, bw end %d", + ch_freq_list[i], bw_val, bw_start, bw_end); + /* found freq/bw pair which is safe for used as sap channel + * avoidance csa target channel/bandwidth. + */ + *selected_freq = ch_freq_list[i]; + *selected_ch_width = ch_params.ch_width; + sap_debug("selected freq %d bw %d", *selected_freq, + *selected_ch_width); + + return QDF_STATUS_SUCCESS; + } + + ch_width = wlan_reg_get_next_lower_bandwidth(ch_width); + if (!(wlan_reg_get_bw_value(ch_width) < 20 || + ch_width == CH_WIDTH_INVALID)) + goto next_lower_bw; + + return QDF_STATUS_E_INVAL; +} + /** * wlansap_get_safe_channel() - Get safe channel from current regulatory * @sap_ctx: Pointer to SAP context + * @ch_width: selected channel bandwdith * * This function is used to get safe channel from current regulatory valid * channels to restart SAP if failed to get safe channel from PCL. @@ -3313,13 +3437,15 @@ bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx) * failure, the channel number returned is zero. */ static uint32_t -wlansap_get_safe_channel(struct sap_context *sap_ctx) +wlansap_get_safe_channel(struct sap_context *sap_ctx, + enum phy_ch_width *ch_width) { struct mac_context *mac; uint32_t pcl_freqs[NUM_CHANNELS]; QDF_STATUS status; mac_handle_t mac_handle; uint32_t pcl_len = 0, i; + uint32_t selected_freq; if (!sap_ctx) { sap_err("NULL parameter"); @@ -3358,6 +3484,15 @@ wlansap_get_safe_channel(struct sap_context *sap_ctx) return INVALID_CHANNEL_ID; } + status = + wlansap_select_chan_with_best_bandwidth(sap_ctx, + pcl_freqs, + pcl_len, + &selected_freq, + ch_width); + if (QDF_IS_STATUS_SUCCESS(status)) + return selected_freq; + for (i = 0; i < pcl_len; i++) { if (WLAN_REG_IS_SAME_BAND_FREQS(sap_ctx->chan_freq, pcl_freqs[i])) { @@ -3377,6 +3512,7 @@ wlansap_get_safe_channel(struct sap_context *sap_ctx) /** * wlansap_get_safe_channel() - Get safe channel from current regulatory * @sap_ctx: Pointer to SAP context + * @ch_width: selected channel width * * This function is used to get safe channel from current regulatory valid * channels to restart SAP if failed to get safe channel from PCL. @@ -3385,14 +3521,16 @@ wlansap_get_safe_channel(struct sap_context *sap_ctx) * failure, the channel number returned is zero. */ static uint8_t -wlansap_get_safe_channel(struct sap_context *sap_ctx) +wlansap_get_safe_channel(struct sap_context *sap_ctx, + enum phy_ch_width *ch_width) { return 0; } #endif uint32_t -wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx) +wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx, + enum phy_ch_width *ch_width) { struct mac_context *mac; struct sir_pcl_list pcl = {0}; @@ -3415,7 +3553,7 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx) if (policy_mgr_get_connection_count(mac->psoc) == 1) { sap_debug("only SAP present return best channel from ACS list"); - return wlansap_get_safe_channel(sap_ctx); + return wlansap_get_safe_channel(sap_ctx, ch_width); } status = @@ -3453,7 +3591,7 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx) * channel is unsafe channel, the pcl may be empty, instead of return, * try to choose a safe channel from acs range. */ - return wlansap_get_safe_channel(sap_ctx); + return wlansap_get_safe_channel(sap_ctx, ch_width); } static uint32_t wlansap_get_2g_first_safe_chan_freq(struct sap_context *sap_ctx) @@ -3665,7 +3803,8 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx, !utils_dfs_is_freq_in_nol(mac->pdev, sap_ctx->chan_freq)) { sap_debug("channel is disabled"); *csa_reason = CSA_REASON_CHAN_DISABLED; - return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx); + return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx, + NULL); } else if (wlan_reg_is_passive_for_freq(mac->pdev, sap_ctx->chan_freq)) { sap_ctx->chan_freq_before_switch_band = sap_ctx->chan_freq; @@ -3680,7 +3819,8 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx, sap_ctx->chan_freq)) { sap_debug("channel is unsafe"); *csa_reason = CSA_REASON_UNSAFE_CHANNEL; - return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx); + return wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx, + NULL); } else { sap_debug("No need switch SAP/Go channel"); return 0;