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 d902f7ee4327..141ce08f47a2 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 @@ -210,6 +210,24 @@ QDF_STATUS policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc, uint8_t *sta_sap_scc_on_dfs_chnl); +/** + * policy_mgr_is_bonded_chan_dfs() - check whether the given bonded + * channel configuration falls under DFS + * @psoc: pointer to psoc + * @ch_width: channel width of the operating channel + * @mhz_freq_seg1: center frequency of segment 1; used for 80+80 MHz + * @chan_freq: primary/operating channel frequency in MHz + * + * This API checks whether the given channel or bonded channel span + * includes DFS, based on the channel width and frequency segments. + * + * Return: true if the given bonded channel is DFS, else false. + */ +bool +policy_mgr_is_bonded_chan_dfs(struct wlan_objmgr_psoc *psoc, + enum phy_ch_width ch_width, + qdf_freq_t mhz_freq_seg1, + uint32_t chan_freq); /** * policy_mgr_get_dfs_master_dynamic_enabled() - support dfs master or not * on AP interafce when STA+SAP(GO) concurrency diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 5661c5a03491..0bffbe5e612e 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -181,6 +181,45 @@ policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +bool +policy_mgr_is_bonded_chan_dfs(struct wlan_objmgr_psoc *psoc, + enum phy_ch_width ch_width, + qdf_freq_t mhz_freq_seg1, + uint32_t chan_freq) +{ + bool is_ch_dfs = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return false; + } + + if (ch_width == CH_WIDTH_160MHZ) { + if (wlan_reg_get_5g_bonded_channel_state_for_freq(pm_ctx->pdev, + chan_freq, + ch_width) + == CHANNEL_STATE_DFS) + is_ch_dfs = true; + } else if (ch_width == CH_WIDTH_80P80MHZ) { + if (wlan_reg_get_channel_state_for_freq( + pm_ctx->pdev, + chan_freq) == + CHANNEL_STATE_DFS || + wlan_reg_get_channel_state_for_freq( + pm_ctx->pdev, + mhz_freq_seg1) == + CHANNEL_STATE_DFS) + is_ch_dfs = true; + } else { + if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, chan_freq)) + is_ch_dfs = true; + } + + return is_ch_dfs; +} + static bool policy_mgr_update_dfs_master_dynamic_enabled( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 80659541d94a..76a1a5228125 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5244,6 +5244,7 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, bool deliver_start_evt = true; struct s_ext_cap *p_ext_cap; enum reg_phymode reg_phy_mode, updated_phy_mode; + bool dfs_master_capable; hdd_enter(); @@ -5787,6 +5788,24 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, config->ch_width_orig = CH_WIDTH_20MHZ; } + status = ucfg_mlme_get_dfs_master_capability(hdd_ctx->psoc, + &dfs_master_capable); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to get dfs master capable"); + ret = -EINVAL; + goto error; + } + + if (!dfs_master_capable && + policy_mgr_is_bonded_chan_dfs(hdd_ctx->psoc, + config->ch_width_orig, + config->ch_params.mhz_freq_seg1, + config->chan_freq)) { + hdd_err("Failed to bringup SAP; Atleast one bonded channel is DFS"); + ret = -EINVAL; + goto error; + } + if (wlan_hdd_setup_driver_overrides(adapter)) { ret = -EINVAL; goto error;