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 a2a5d6e34b59..7dcf9950e5f3 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 @@ -624,6 +624,20 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t channel, enum hw_mode_bandwidth bw); +/** + * policy_mgr_nan_sap_pre_enable_conc_check() - Check if NAN+SAP SCC is + * allowed in given ch + * @psoc: PSOC object information + * @mode: Connection mode + * @ch: channel to check + * + * Return: True if allowed else false + */ +bool +policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t ch); + /** * policy_mgr_allow_concurrency_csa() - Check for allowed concurrency * combination when channel switch @@ -2833,6 +2847,24 @@ bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, void policy_mgr_update_user_config_sap_chan( struct wlan_objmgr_psoc *psoc, uint32_t channel); +/** + * policy_mgr_nan_sap_post_enable_conc_check() - Do concurrency operations + * post nan/sap enable + * @psoc: poniter to psoc + * + * Return: void + **/ +void policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_nan_sap_post_disable_conc_check() - Do concurrency related + * operation post nan/sap disable + * @psoc: poniter to psoc + * + * Return: void + **/ +void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_is_sap_restart_required_after_sta_disconnect() - is sap restart * required @@ -2860,6 +2892,17 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect( */ bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch); +/** + * policy_mgr_nan_sap_scc_on_unsafe_ch_chk() - check whether SAP is doing SCC + * with NAN + * @psoc: poniter to psoc + * @sap_ch: operating channel of SAP interface + * + * Return: true or false + */ +bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc, + uint8_t sap_ch); + /** * policy_mgr_get_hw_mode_from_idx() - Get HW mode based on index * @psoc: psoc object diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h index 2edbd035ec7b..56aa26762521 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h @@ -454,6 +454,29 @@ CFG_INI_UINT("gForce1x1Exception", 0, 1, 1, CFG_VALUE_OR_DEFAULT, \ CFG_INI_UINT("gEnableSAPManadatoryChanList", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \ "Enable SAP Mandatory channel list") +/* + * + * g_nan_sap_scc_on_lte_coex_chan - Allow NAN+SAP SCC on LTE coex channel + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to allow NAN+SAP SCC on LTE coex channel + * 0 - Disallow NAN+SAP SCC on LTE coex channel + * 1 - Allow NAN+SAP SCC on LTE coex channel + * + * Related: Depends on gWlanMccToSccSwitchMode config. + * + * Supported Feature: Non-DBS, DBS + * + * Usage: Internal/External + * + * + */ +#define CFG_NAN_SAP_SCC_ON_LTE_COEX_CHAN \ +CFG_INI_BOOL("g_nan_sap_scc_on_lte_coex_chan", 1, \ + "Allow NAN+SAP SCC on LTE coex channel") + /* * * g_sta_sap_scc_on_lte_coex_chan - Allow STA+SAP SCC on LTE coex channel @@ -521,6 +544,7 @@ CFG_INI_UINT("g_mark_sap_indoor_as_disable", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \ CFG(CFG_FORCE_1X1_FEATURE)\ CFG(CFG_ENABLE_SAP_MANDATORY_CHAN_LIST)\ CFG(CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN)\ + CFG(CFG_NAN_SAP_SCC_ON_LTE_COEX_CHAN) \ CFG(CFG_MARK_INDOOR_AS_DISABLE_FEATURE)\ CFG(CFG_ALLOW_MCC_GO_DIFF_BI) #endif 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 533112faace8..9cbe44bfaf7e 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 @@ -32,6 +32,8 @@ #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" #include "qdf_platform.h" +#include "wlan_nan_api.h" +#include "nan_ucfg_api.h" enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) (struct wlan_objmgr_psoc *psoc); @@ -464,6 +466,15 @@ bool policy_mgr_is_dbs_allowed_for_concurrency( break; } break; + case PM_NAN_DISC_MODE: + switch (new_conn_mode) { + case QDF_STA_MODE: + case QDF_SAP_MODE: + return true; + default: + return false; + } + break; default: break; } @@ -1353,6 +1364,258 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect( return true; } +/** + * policy_mgr_is_nan_sap_unsafe_ch_scc_allowed() - Check if NAN+SAP SCC is + * allowed in LTE COEX unsafe ch + * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context + * @ch: Channel to check + * + * Return: True if allowed else false + */ +static bool +policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(struct policy_mgr_psoc_priv_obj + *pm_ctx, uint8_t ch) +{ + if (policy_mgr_is_safe_channel(pm_ctx->psoc, ch) || + pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl) + return true; + + return false; +} + +/** + * policy_mgr_nan_disable_work() - qdf defer function wrapper for NAN disable + * @data: qdf_work data + * + * Return: None + */ +static void policy_mgr_nan_disable_work(void *data) +{ + struct wlan_objmgr_psoc *psoc = data; + + ucfg_nan_disable_concurrency(psoc); +} + +bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc, + uint8_t sap_ch) +{ + uint8_t nan_ch_2g, nan_ch_5g; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + nan_ch_2g = policy_mgr_mode_specific_get_channel(psoc, + PM_NAN_DISC_MODE); + if (nan_ch_2g == 0) { + policy_mgr_debug("No NAN+SAP SCC"); + return false; + } + nan_ch_5g = wlan_nan_get_disc_5g_ch(psoc); + + if (WLAN_REG_IS_SAME_BAND_CHANNELS(nan_ch_2g, sap_ch)) { + if (policy_mgr_is_force_scc(pm_ctx->psoc) && + policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, + nan_ch_2g)) + return true; + } else if (WLAN_REG_IS_SAME_BAND_CHANNELS(nan_ch_5g, sap_ch)) { + if (policy_mgr_is_force_scc(pm_ctx->psoc) && + policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, + nan_ch_5g)) + return true; + } + policy_mgr_debug("NAN+SAP unsafe ch SCC not allowed. Disabling NAN"); + /* change context to worker since this is executed in sched thread ctx*/ + qdf_create_work(0, &pm_ctx->nan_sap_conc_work, + policy_mgr_nan_disable_work, psoc); + qdf_sched_work(0, &pm_ctx->nan_sap_conc_work); + + return false; +} + +bool +policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t ch) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint8_t sap_ch, nan_ch_2g, nan_ch_5g; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + if (!(mode == PM_SAP_MODE || mode == PM_NAN_DISC_MODE)) { + policy_mgr_debug("Not NAN or SAP mode"); + return true; + } + + if (!ch) { + policy_mgr_err("Invalid channel"); + return false; + } + + if (!wlan_nan_get_sap_conc_support(pm_ctx->psoc)) { + policy_mgr_debug("NAN+SAP not supported in fw"); + if (mode == PM_NAN_DISC_MODE) + return false; + /* Before SAP start disable NAN */ + ucfg_nan_disable_concurrency(pm_ctx->psoc); + } + if (mode == PM_NAN_DISC_MODE) { + sap_ch = policy_mgr_mode_specific_get_channel(pm_ctx->psoc, + PM_SAP_MODE); + policy_mgr_debug("SAP CH: %d NAN Ch: %d", sap_ch, ch); + if (WLAN_REG_IS_SAME_BAND_CHANNELS(sap_ch, ch)) { + if (sap_ch == ch) { + policy_mgr_debug("NAN+SAP SCC"); + return true; + } + + if (!policy_mgr_is_force_scc(pm_ctx->psoc)) { + policy_mgr_debug("SAP force SCC disabled"); + return false; + } + if (!policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx, + ch)) { + policy_mgr_debug("NAN+SAP unsafe ch SCC disabled"); + return false; + } + } + } else if (mode == PM_SAP_MODE) { + nan_ch_2g = + policy_mgr_mode_specific_get_channel(pm_ctx->psoc, + PM_NAN_DISC_MODE); + nan_ch_5g = wlan_nan_get_disc_5g_ch(pm_ctx->psoc); + policy_mgr_debug("SAP CH: %d NAN Ch: %d %d", ch, nan_ch_2g, + nan_ch_5g); + if (WLAN_REG_IS_SAME_BAND_CHANNELS(nan_ch_2g, ch) || + WLAN_REG_IS_SAME_BAND_CHANNELS(nan_ch_5g, ch)) { + if (ch == nan_ch_2g || ch == nan_ch_5g) { + policy_mgr_debug("NAN+SAP SCC"); + return true; + } + if (!policy_mgr_is_force_scc(pm_ctx->psoc)) { + policy_mgr_debug("SAP force SCC disabled"); + ucfg_nan_disable_concurrency(pm_ctx->psoc); + return false; + } + if ((WLAN_REG_IS_5GHZ_CH(ch) && + !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( + pm_ctx, nan_ch_5g)) || + (WLAN_REG_IS_24GHZ_CH(ch) && + !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed( + pm_ctx, nan_ch_2g))) { + policy_mgr_debug("NAN+SAP unsafe ch SCC disabled"); + ucfg_nan_disable_concurrency(pm_ctx->psoc); + return false; + } + } + } + return true; +} + +void policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + struct policy_mgr_conc_connection_info *sap_info = NULL; + uint8_t sap_ch = 0, nan_ch_2g, nan_ch_5g, i; + QDF_STATUS status; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid pm context"); + return; + } + + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + if (pm_conc_connection_list[i].mode == PM_SAP_MODE && + pm_conc_connection_list[i].in_use) { + sap_info = &pm_conc_connection_list[i]; + sap_ch = sap_info->chan; + break; + } + } + if (sap_ch == 0) + return; + nan_ch_2g = policy_mgr_mode_specific_get_channel(psoc, + PM_NAN_DISC_MODE); + nan_ch_5g = wlan_nan_get_disc_5g_ch(psoc); + if (sap_ch == nan_ch_2g || sap_ch == nan_ch_5g) { + policy_mgr_debug("NAN and SAP already in SCC"); + return; + } + if (nan_ch_2g == 0) + return; + + status = qdf_wait_single_event(&pm_ctx->channel_switch_complete_evt, + CHANNEL_SWITCH_COMPLETE_TIMEOUT); + policy_mgr_reset_chan_switch_complete_evt(psoc); + if (!QDF_IS_STATUS_SUCCESS(status)) + policy_mgr_err("SAP Ch Switch wait fail. Force new Ch switch"); + + policy_mgr_debug("Force SCC for NAN+SAP Ch: %d", + WLAN_REG_IS_5GHZ_CH(sap_ch) ? nan_ch_5g : nan_ch_2g); + if (WLAN_REG_IS_5GHZ_CH(sap_ch)) { + policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, + nan_ch_5g, + policy_mgr_get_ch_width( + sap_info->bw), + true); + } else { + policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, + nan_ch_2g, + policy_mgr_get_ch_width( + sap_info->bw), + true); + } +} + +void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + struct policy_mgr_conc_connection_info *sap_info = NULL; + uint8_t sap_ch = 0, i; + QDF_STATUS status; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid pm context"); + return; + } + + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + if (pm_conc_connection_list[i].mode == PM_SAP_MODE && + pm_conc_connection_list[i].in_use) { + sap_info = &pm_conc_connection_list[i]; + sap_ch = sap_info->chan; + break; + } + } + if (sap_ch == 0 || policy_mgr_is_safe_channel(psoc, sap_ch)) + return; + + sap_ch = policy_mgr_get_nondfs_preferred_channel(psoc, PM_SAP_MODE, + false); + policy_mgr_debug("User/ACS orig ch: %d New SAP ch: %d", + pm_ctx->user_config_sap_channel, sap_ch); + status = qdf_wait_single_event(&pm_ctx->channel_switch_complete_evt, + CHANNEL_SWITCH_COMPLETE_TIMEOUT); + policy_mgr_reset_chan_switch_complete_evt(psoc); + if (!QDF_IS_STATUS_SUCCESS(status)) + policy_mgr_err("SAP Ch Switch wait fail. Force new Ch switch"); + + policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id, + sap_ch, + policy_mgr_get_ch_width( + sap_info->bw), true); +} + static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) { struct wlan_objmgr_psoc *psoc; diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index 8774696de01a..572c316763e4 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -1557,6 +1557,40 @@ enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width) return bw; } +enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw) +{ + enum phy_ch_width ch_width = CH_WIDTH_INVALID; + + switch (bw) { + case HW_MODE_20_MHZ: + ch_width = CH_WIDTH_20MHZ; + break; + case HW_MODE_40_MHZ: + ch_width = CH_WIDTH_40MHZ; + break; + case HW_MODE_80_MHZ: + ch_width = CH_WIDTH_80MHZ; + break; + case HW_MODE_160_MHZ: + ch_width = CH_WIDTH_160MHZ; + break; + case HW_MODE_80_PLUS_80_MHZ: + ch_width = CH_WIDTH_80P80MHZ; + break; + case HW_MODE_5_MHZ: + ch_width = CH_WIDTH_5MHZ; + break; + case HW_MODE_10_MHZ: + ch_width = CH_WIDTH_10MHZ; + break; + default: + policy_mgr_err("Invalid phy_ch_width type %d", ch_width); + break; + } + + return ch_width; +} + /** * policy_mgr_get_sbs_channels() - provides the sbs channel(s) * with respect to current connection(s) @@ -1931,6 +1965,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, return status; } + *len = 0; if (PM_MAX_PCL_TYPE == pcl) { /* msg */ policy_mgr_err("pcl is invalid"); diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h index 391bc5511b9f..9eb359c0bf7b 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h @@ -226,6 +226,7 @@ struct sta_ap_intf_check_work_ctx { * @is_force_1x1_enable: Is 1x1 forced for connection * @sta_sap_scc_on_dfs_chnl: STA-SAP SCC on DFS channel * @sta_sap_scc_on_lte_coex_chnl: STA-SAP SCC on LTE Co-ex channel + * @nan_sap_scc_on_lte_coex_chnl: NAN-SAP SCC on LTE Co-ex channel * @sap_mandatory_chnl_enable: To enable/disable SAP mandatory channels * @mark_indoor_chnl_disable: Mark indoor channel as disable or enable * @dbs_selection_plcy: DBS selection policy for concurrency @@ -247,6 +248,7 @@ struct policy_mgr_cfg { uint8_t is_force_1x1_enable; uint8_t sta_sap_scc_on_dfs_chnl; uint8_t sta_sap_scc_on_lte_coex_chnl; + uint8_t nan_sap_scc_on_lte_coex_chnl; uint8_t sap_mandatory_chnl_enable; uint8_t mark_indoor_chnl_disable; uint8_t enable_sta_cxn_5g_band; @@ -301,6 +303,7 @@ struct policy_mgr_cfg { * @unsafe_channel_list: LTE coex channel avoidance list * @unsafe_channel_count: LTE coex channel avoidance list count * @sta_ap_intf_check_work_info: Info related to sta_ap_intf_check_work + * @nan_sap_conc_work: Info related to nan sap conc work * @opportunistic_update_done_evt: qdf event to synchronize host * & FW HW mode */ @@ -323,6 +326,7 @@ struct policy_mgr_psoc_priv_obj { uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE]; uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE]; qdf_work_t sta_ap_intf_check_work; + qdf_work_t nan_sap_conc_work; uint32_t num_dbs_hw_modes; struct dbs_hw_mode_info hw_mode; uint32_t old_hw_mode_index; @@ -482,6 +486,15 @@ void pm_dbs_opportunistic_timer_handler(void *data); enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type, uint8_t subtype); enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width); + +/** + * policy_mgr_get_bw() - Convert hw_mode_bandwidth to phy_ch_width + * @bw: Hardware mode band width used by WMI + * + * Return: phy_ch_width + */ +enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw); + QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, enum policy_mgr_pcl_type pcl, uint8_t *pcl_channels, uint32_t *len, diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c index f53791e93724..5570b4562643 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c @@ -1516,7 +1516,8 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, } for (i = 0; i < pcl_len; i++) { - if (wlan_reg_is_dfs_ch(pm_ctx->pdev, pcl_channels[i])) { + if (wlan_reg_is_dfs_ch(pm_ctx->pdev, pcl_channels[i]) || + !policy_mgr_is_safe_channel(psoc, pcl_channels[i])) { continue; } else { channel = pcl_channels[i]; diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c index 6bf6b4e40c19..10671ef7af93 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c @@ -54,6 +54,8 @@ static QDF_STATUS policy_mgr_init_cfg(struct wlan_objmgr_psoc *psoc) cfg_get(psoc, CFG_FORCE_1X1_FEATURE); cfg->sta_sap_scc_on_dfs_chnl = cfg_get(psoc, CFG_STA_SAP_SCC_ON_DFS_CHAN); + cfg->nan_sap_scc_on_lte_coex_chnl = + cfg_get(psoc, CFG_NAN_SAP_SCC_ON_LTE_COEX_CHAN); cfg->sta_sap_scc_on_lte_coex_chnl = cfg_get(psoc, CFG_STA_SAP_SCC_ON_LTE_COEX_CHAN); cfg->sap_mandatory_chnl_enable =