diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 832316cddc..f26e3b4c3a 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -2928,6 +2928,7 @@ bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc); * @con_ch_freq: pointer to the chan freq on which sap will come up * @sap_ch_freq: initial channel frequency for SAP * @sap_vdev_id: sap vdev id. + * @ch_params: sap channel parameters * * This function checks & updates the channel SAP to come up on in * case of STA+SAP concurrency @@ -2935,7 +2936,8 @@ bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc); */ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( struct wlan_objmgr_psoc *psoc, uint32_t *con_ch_freq, - uint32_t sap_ch_freq, uint8_t sap_vdev_id); + uint32_t sap_ch_freq, uint8_t sap_vdev_id, + struct ch_params *ch_params); /** * policy_mgr_get_alternate_channel_for_sap() - Get an alternate 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 e523c67217..5111fd9716 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 @@ -33,6 +33,7 @@ #include "qdf_platform.h" #include "wlan_nan_api.h" #include "nan_ucfg_api.h" +#include "wlan_mlme_api.h" #include "sap_api.h" enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) @@ -2049,12 +2050,14 @@ static QDF_STATUS policy_mgr_check_6ghz_sap_conc( QDF_STATUS policy_mgr_valid_sap_conc_channel_check( struct wlan_objmgr_psoc *psoc, uint32_t *con_ch_freq, - uint32_t sap_ch_freq, uint8_t sap_vdev_id) + uint32_t sap_ch_freq, uint8_t sap_vdev_id, + struct ch_params *ch_params) { uint32_t ch_freq = *con_ch_freq; uint32_t temp_ch_freq = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; bool sta_sap_scc_on_dfs_chan; + bool is_dfs; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -2089,9 +2092,10 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); - + is_dfs = wlan_mlme_check_chan_param_has_dfs( + pm_ctx->pdev, ch_params, ch_freq); if (policy_mgr_valid_sta_channel_check(psoc, ch_freq)) { - if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq) || + if (is_dfs || wlan_reg_is_passive_or_disable_for_freq(pm_ctx->pdev, ch_freq) || !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) || @@ -2100,8 +2104,7 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( pm_ctx->pdev) && wlan_reg_is_etsi13_srd_chan_for_freq(pm_ctx->pdev, ch_freq))) { - if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq) && - sta_sap_scc_on_dfs_chan) { + if (is_dfs && sta_sap_scc_on_dfs_chan) { policy_mgr_debug("STA SAP SCC is allowed on DFS channel"); goto update_chan; } diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 44fbc10c53..30ba355951 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -2904,4 +2904,17 @@ wlan_mlme_get_bss_load_rssi_threshold_5ghz(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_get_bss_load_rssi_threshold_24ghz(struct wlan_objmgr_psoc *psoc, int32_t *val); +/** + * wlan_mlme_check_chan_param_has_dfs() - Get dfs flag based on + * channel & channel parameters + * @pdev: pdev object + * @ch_params: channel parameters + * @chan_freq: channel frequency in MHz + * + * Return: True for dfs + */ +bool +wlan_mlme_check_chan_param_has_dfs(struct wlan_objmgr_pdev *pdev, + struct ch_params *ch_params, + uint32_t chan_freq); #endif /* _WLAN_MLME_API_H_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 173573b8a9..7fcacae4aa 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -4413,3 +4413,31 @@ wlan_mlme_get_bss_load_rssi_threshold_24ghz(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } + +bool +wlan_mlme_check_chan_param_has_dfs(struct wlan_objmgr_pdev *pdev, + struct ch_params *ch_params, + uint32_t chan_freq) +{ + bool is_dfs = false; + + if (ch_params->ch_width == CH_WIDTH_160MHZ) { + is_dfs = true; + } else if (ch_params->ch_width == CH_WIDTH_80P80MHZ) { + if (wlan_reg_get_channel_state_for_freq( + pdev, + chan_freq) == CHANNEL_STATE_DFS || + wlan_reg_get_channel_state_for_freq( + pdev, + ch_params->mhz_freq_seg1) == CHANNEL_STATE_DFS) + is_dfs = true; + } else if (wlan_reg_get_channel_state_for_freq( + pdev, chan_freq) == CHANNEL_STATE_DFS) { + is_dfs = true; + } + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq) || + WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) + is_dfs = false; + + return is_dfs; +} diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index c51216ea0f..bc5d6b7572 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -3184,10 +3184,10 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( struct hdd_ap_ctx *hdd_ap_ctx; struct hdd_context *hdd_ctx; uint8_t mcc_to_scc_switch = 0; - struct ch_params ch_params; + struct ch_params ch_params = {0}; struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev( psoc, vdev_id); - uint32_t sap_ch_freq, intf_ch_freq; + uint32_t sap_ch_freq, intf_ch_freq, temp_ch_freq; struct sap_context *sap_context; enum sap_csa_reason_code csa_reason = CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL; @@ -3272,11 +3272,18 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart( intf_ch_freq = wlansap_check_cc_intf(sap_context); hdd_debug("sap_vdev %d intf_ch: %d, orig freq: %d", vdev_id, intf_ch_freq, sap_ch_freq); + + temp_ch_freq = intf_ch_freq ? intf_ch_freq : sap_ch_freq; + ch_params.ch_width = wlansap_get_csa_chanwidth_from_phymode( + sap_context, temp_ch_freq); + wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev, temp_ch_freq, 0, + &ch_params); if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION != mcc_to_scc_switch) { if (QDF_IS_STATUS_ERROR( policy_mgr_valid_sap_conc_channel_check( - hdd_ctx->psoc, &intf_ch_freq, sap_ch_freq, vdev_id))) { + hdd_ctx->psoc, &intf_ch_freq, sap_ch_freq, vdev_id, + &ch_params))) { wlansap_context_put(sap_context); hdd_debug("can't move sap to chan(freq): %u", intf_ch_freq); diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 4679bf3e17..d4a2fc0125 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -1151,6 +1151,18 @@ QDF_STATUS wlansap_set_dfs_ignore_cac(mac_handle_t mac_handle, QDF_STATUS wlansap_get_dfs_cac_state(mac_handle_t mac_handle, eSapDfsCACState_t *cac_state); +/** + * wlansap_get_csa_chanwidth_from_phymode() - function to populate + * channel width from user configured phymode for csa + * @sap_context: sap adapter context + * @chan_freq: target channel frequency (MHz) + * + * Return: phy_ch_width + */ +enum phy_ch_width +wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context, + uint32_t chan_freq); + #ifdef FEATURE_AP_MCC_CH_AVOIDANCE QDF_STATUS wlan_sap_set_channel_avoidance(mac_handle_t mac_handle, diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index c2d62715a7..c67393d2b3 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -740,6 +740,7 @@ sap_validate_chan(struct sap_context *sap_context, uint32_t sta_sap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK; uint32_t concurrent_state; bool go_force_scc; + struct ch_params ch_params; mac_handle = cds_get_context(QDF_MODULE_ID_SME); mac_ctx = MAC_CONTEXT(mac_handle); @@ -783,13 +784,19 @@ sap_validate_chan(struct sap_context *sap_context, QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("After check overlap: con_ch:%d"), con_ch_freq); + ch_params = sap_context->ch_params; + if (con_ch_freq && + WLAN_REG_IS_24GHZ_CH_FREQ(con_ch_freq)) + ch_params.ch_width = CH_WIDTH_20MHZ; + if (sap_context->cc_switch_mode != QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) { if (QDF_IS_STATUS_ERROR( policy_mgr_valid_sap_conc_channel_check( mac_ctx->psoc, &con_ch_freq, sap_context->chan_freq, - sap_context->sessionId))) { + sap_context->sessionId, + &ch_params))) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, FL("SAP can't start (no MCC)")); @@ -802,13 +809,18 @@ sap_validate_chan(struct sap_context *sap_context, sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( mac_ctx->psoc); + ch_params = sap_context->ch_params; + if (con_ch_freq && + WLAN_REG_IS_24GHZ_CH_FREQ(con_ch_freq)) + ch_params.ch_width = CH_WIDTH_20MHZ; if (con_ch_freq && (policy_mgr_sta_sap_scc_on_lte_coex_chan( mac_ctx->psoc) || policy_mgr_is_safe_channel( mac_ctx->psoc, con_ch_freq)) && - (!wlan_reg_is_dfs_for_freq( - mac_ctx->pdev, con_ch_freq) || + (!wlan_mlme_check_chan_param_has_dfs( + mac_ctx->pdev, &ch_params, + con_ch_freq) || sta_sap_scc_on_dfs_chan)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 69dcb47109..186da47920 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -1186,26 +1186,12 @@ QDF_STATUS wlansap_deauth_sta(struct sap_context *sap_ctx, params); } -/** - * wlansap_update_csa_channel_params() - function to populate channel width and - * bonding modes. - * @sap_context: sap adapter context - * @channel: target channel - * - * Return: The QDF_STATUS code associated with performing the operation - */ -static QDF_STATUS -wlansap_update_csa_channel_params(struct sap_context *sap_context, - uint32_t chan_freq) +enum phy_ch_width +wlansap_get_csa_chanwidth_from_phymode(struct sap_context *sap_context, + uint32_t chan_freq) { - struct mac_context *mac_ctx; uint32_t max_fw_bw; - - mac_ctx = sap_get_mac_context(); - if (!mac_ctx) { - QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context"); - return QDF_STATUS_E_FAULT; - } + enum phy_ch_width ch_width; if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { /* @@ -1213,7 +1199,7 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context, * SAP coming up in HT40 on channel switch we are * disabling channel bonding in 2.4Ghz. */ - mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_20MHZ; + ch_width = CH_WIDTH_20MHZ; } else { if (sap_context->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11ac || @@ -1225,23 +1211,21 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context, eCSR_DOT11_MODE_11ax_ONLY) { max_fw_bw = sme_get_vht_ch_width(); if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) - mac_ctx->sap.SapDfsInfo.new_chanWidth = - CH_WIDTH_160MHZ; + ch_width = CH_WIDTH_160MHZ; else - mac_ctx->sap.SapDfsInfo.new_chanWidth = - CH_WIDTH_80MHZ; + 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) { - mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_40MHZ; + ch_width = CH_WIDTH_40MHZ; } else { /* For legacy 11a mode return 20MHz */ - mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_20MHZ; + ch_width = CH_WIDTH_20MHZ; } } - return QDF_STATUS_SUCCESS; + return ch_width; } /** @@ -1293,6 +1277,63 @@ static char *sap_get_csa_reason_str(enum sap_csa_reason_code reason) } } +/** + * wlansap_set_chan_params_for_csa() - Update sap channel parameters + * for channel switch + * @mac: mac ctx + * @sap_ctx: sap context + * @target_chan_freq: target channel frequency in MHz + * @target_bw: target bandwidth + * + * Return: QDF_STATUS_SUCCESS for success. + */ +static QDF_STATUS +wlansap_set_chan_params_for_csa(struct mac_context *mac, + struct sap_context *sap_ctx, + uint32_t target_chan_freq, + enum phy_ch_width target_bw) +{ + mac->sap.SapDfsInfo.new_chanWidth = + wlansap_get_csa_chanwidth_from_phymode(sap_ctx, + target_chan_freq); + /* + * Copy the requested target channel + * to sap context. + */ + mac->sap.SapDfsInfo.target_chan_freq = target_chan_freq; + mac->sap.SapDfsInfo.new_ch_params.ch_width = + mac->sap.SapDfsInfo.new_chanWidth; + + /* By this time, the best bandwidth is calculated for + * the given target channel. Now, if there was a + * request from user to move to a selected bandwidth, + * we can see if it can be honored. + * + * Ex1: BW80 was selected for the target channel and + * user wants BW40, it can be allowed + * Ex2: BW40 was selected for the target channel and + * user wants BW80, it cannot be allowed for the given + * target channel. + * + * So, the MIN of the selected channel bandwidth and + * user input is used for the bandwidth + */ + if (target_bw != CH_WIDTH_MAX) { + sap_nofl_debug("SAP CSA: target bw:%d new width:%d", + target_bw, + mac->sap.SapDfsInfo.new_ch_params.ch_width); + mac->sap.SapDfsInfo.new_ch_params.ch_width = + mac->sap.SapDfsInfo.new_chanWidth = + QDF_MIN(mac->sap.SapDfsInfo.new_ch_params.ch_width, + target_bw); + } + wlan_reg_set_channel_params_for_freq( + mac->pdev, target_chan_freq, 0, + &mac->sap.SapDfsInfo.new_ch_params); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, uint32_t target_chan_freq, enum phy_ch_width target_bw, @@ -1303,6 +1344,9 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, bool valid; QDF_STATUS status, hw_mode_status; bool sta_sap_scc_on_dfs_chan; + bool is_dfs; + struct ch_params tmp_ch_params = {0}; + enum channel_state state; if (!sap_ctx) { sap_err("Invalid SAP pointer"); @@ -1328,23 +1372,45 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, mac->psoc, sap_ctx->sessionId, POLICY_MGR_BAND_5), sap_get_csa_reason_str(sap_ctx->csa_reason), sap_ctx->csa_reason, strict, sap_ctx->sessionId); + if (sap_ctx->chan_freq == target_chan_freq) + return QDF_STATUS_E_FAULT; + + state = wlan_reg_get_channel_state_for_freq(mac->pdev, + target_chan_freq); + if (state == CHANNEL_STATE_DISABLE || state == CHANNEL_STATE_INVALID) { + sap_nofl_debug("invalid target freq %d state %d", + target_chan_freq, state); + return QDF_STATUS_E_INVAL; + } 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); + if (target_bw != CH_WIDTH_MAX) { + tmp_ch_params.ch_width = + QDF_MIN(tmp_ch_params.ch_width, target_bw); + sap_nofl_debug("target ch_width %d to %d ", target_bw, + tmp_ch_params.ch_width); + } + + wlan_reg_set_channel_params_for_freq(mac->pdev, target_chan_freq, 0, + &tmp_ch_params); + is_dfs = wlan_mlme_check_chan_param_has_dfs( + mac->pdev, &tmp_ch_params, + target_chan_freq); /* * Now, validate if the passed channel is valid in the * current regulatory domain. */ - if (sap_ctx->chan_freq != target_chan_freq && - ((wlan_reg_get_channel_state_for_freq(mac->pdev, target_chan_freq) == - CHANNEL_STATE_ENABLE) || - (wlan_reg_get_channel_state_for_freq(mac->pdev, target_chan_freq) == - CHANNEL_STATE_DFS && - (!policy_mgr_is_any_mode_active_on_band_along_with_session( + if (!is_dfs || + (!policy_mgr_is_any_mode_active_on_band_along_with_session( mac->psoc, sap_ctx->sessionId, POLICY_MGR_BAND_5) || sta_sap_scc_on_dfs_chan || - sap_ctx->csa_reason == CSA_REASON_DCS)))) { + sap_ctx->csa_reason == CSA_REASON_DCS)) { /* * validate target channel switch w.r.t various concurrency * rules set. @@ -1366,9 +1432,10 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, * state. */ if (sap_ctx->fsm_state == SAP_STARTED) { - status = wlansap_update_csa_channel_params(sap_ctx, - target_chan_freq); - if (status != QDF_STATUS_SUCCESS) + status = wlansap_set_chan_params_for_csa( + mac, sap_ctx, target_chan_freq, + target_bw); + if (QDF_IS_STATUS_ERROR(status)) return status; hw_mode_status = @@ -1394,41 +1461,7 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, mac->psoc); return status; } - /* - * Copy the requested target channel - * to sap context. - */ - mac->sap.SapDfsInfo.target_chan_freq = target_chan_freq; - mac->sap.SapDfsInfo.new_ch_params.ch_width = - mac->sap.SapDfsInfo.new_chanWidth; - /* By this time, the best bandwidth is calculated for - * the given target channel. Now, if there was a - * request from user to move to a selected bandwidth, - * we can see if it can be honored. - * - * Ex1: BW80 was selected for the target channel and - * user wants BW40, it can be allowed - * Ex2: BW40 was selected for the target channel and - * user wants BW80, it cannot be allowed for the given - * target channel. - * - * So, the MIN of the selected channel bandwidth and - * user input is used for the bandwidth - */ - if (target_bw != CH_WIDTH_MAX) { - sap_nofl_debug("SAP CSA: target bw:%d new width:%d", - target_bw, - mac->sap.SapDfsInfo. - new_ch_params.ch_width); - mac->sap.SapDfsInfo.new_ch_params.ch_width = - mac->sap.SapDfsInfo.new_chanWidth = - QDF_MIN(mac->sap.SapDfsInfo. - new_ch_params.ch_width, - target_bw); - } - wlan_reg_set_channel_params_for_freq(mac->pdev, target_chan_freq, - 0, &mac->sap.SapDfsInfo.new_ch_params); /* * Set the CSA IE required flag. */ @@ -1472,7 +1505,8 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sap_ctx, } else { sap_err("Channel freq = %d is not valid in the current" - "regulatory domain", target_chan_freq); + "regulatory domain, is_dfs %d", target_chan_freq, + is_dfs); return QDF_STATUS_E_FAULT; }