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 f14630fcb3a8..77a1de789755 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 @@ -760,6 +760,25 @@ enum policy_mgr_two_connection_mode policy_mgr_get_third_connection_pcl_table_index( struct wlan_objmgr_psoc *psoc); +#ifdef FEATURE_FOURTH_CONNECTION +/** + * policy_mgr_get_fourth_connection_pcl_table_index() - provides the + * row index to fourthConnectionPclTable to get to the correct + * pcl + * @psoc: PSOC object information + * + * This function provides the row index to + * fourthConnectionPclTable. The index is derived based on + * current connection, band on which it is on & chain mask it is + * using, as obtained from pm_conc_connection_list. + * + * Return: table index + */ +enum policy_mgr_three_connection_mode + policy_mgr_get_fourth_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc); +#endif + /** * policy_mgr_incr_connection_count() - adds the new connection to * the current connections list diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h index 21c1e2249b89..a1659bae5208 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h @@ -59,7 +59,11 @@ #define MAX_MAC 2 +#ifdef FEATURE_FOURTH_CONNECTION +#define MAX_NUMBER_OF_CONC_CONNECTIONS 4 +#else #define MAX_NUMBER_OF_CONC_CONNECTIONS 3 +#endif typedef int (*send_mode_change_event_cb)(void); @@ -740,6 +744,30 @@ enum policy_mgr_two_connection_mode { PM_MAX_TWO_CONNECTION_MODE }; +#ifdef FEATURE_FOURTH_CONNECTION +/** + * enum policy_mgr_three_connection_mode - Combination of first three + * connections type, concurrency state, band used. + * + * @PM_STA_SAP_SCC_24_SAP_5_DBS: STA & SAP connection on 2.4 Ghz SCC, another + * SAP on 5 G + * @PM_STA_SAP_SCC_5_SAP_24_DBS: STA & SAP connection on 5 Ghz SCC, another + * SAP on 2.4 G + * @PM_STA_SAP_SCC_24_STA_5_DBS: STA & SAP connection on 2.4 Ghz SCC, another + * STA on 5G + * @PM_STA_SAP_SCC_5_STA_24_DBS: STA & SAP connection on 5 Ghz SCC, another + * STA on 2.4 G + */ +enum policy_mgr_three_connection_mode { + PM_STA_SAP_SCC_24_SAP_5_DBS, + PM_STA_SAP_SCC_5_SAP_24_DBS, + PM_STA_SAP_SCC_24_STA_5_DBS, + PM_STA_SAP_SCC_5_STA_24_DBS, + + PM_MAX_THREE_CONNECTION_MODE +}; +#endif + /** * enum policy_mgr_conc_next_action - actions to be taken on old * connections. 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 92da8c306113..256c51b544cf 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 @@ -2044,6 +2044,56 @@ static bool policy_mgr_check_privacy_for_new_conn( return true; } +#ifdef FEATURE_FOURTH_CONNECTION +static bool policy_mgr_is_concurrency_allowed_4_port( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, + struct policy_mgr_pcl_list pcl) +{ + uint32_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + /* new STA may just have ssid, no channel until bssid assigned */ + if (channel == 0 && mode == PM_STA_MODE) + return true; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("context is NULL"); + return false; + } + + if (policy_mgr_get_mcc_to_scc_switch_mode(psoc) != + QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) { + policy_mgr_err("couldn't start 4th port for bad force scc cfg"); + return false; + } + if (pm_ctx->cfg.dual_mac_feature || + !pm_ctx->cfg.sta_sap_scc_on_dfs_chnl || + !pm_ctx->cfg.sta_sap_scc_on_lte_coex_chnl) { + policy_mgr_err( + "Couldn't start 4th port for bad cfg of dual mac, dfs scc, lte coex scc"); + return false; + } + + for (i = 0; i < pcl.pcl_len; i++) + if (channel == pcl.pcl_list[i]) + return true; + + policy_mgr_err("4th port failed on channel %d with mode %d", + channel, mode); + + return false; +} +#else +static inline bool policy_mgr_is_concurrency_allowed_4_port( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, + struct policy_mgr_pcl_list pcl) {return false; } +#endif + bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t channel, @@ -2268,6 +2318,7 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, { QDF_STATUS status; struct policy_mgr_pcl_list pcl; + bool allowed; qdf_mem_zero(&pcl, sizeof(pcl)); status = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len, @@ -2278,7 +2329,17 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, return false; } - return policy_mgr_is_concurrency_allowed(psoc, mode, channel, bw); + allowed = policy_mgr_is_concurrency_allowed( + psoc, mode, channel, bw); + + /* Fourth connection concurrency check */ + if (allowed && policy_mgr_get_connection_count(psoc) == 3) + allowed = policy_mgr_is_concurrency_allowed_4_port( + psoc, + mode, + channel, + pcl); + return allowed; } bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, 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 34230d846cdb..6195172012d9 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 @@ -198,6 +198,14 @@ extern policy_mgr_next_action_two_connection_table_type *next_action_two_connection_table; extern policy_mgr_next_action_three_connection_table_type *next_action_three_connection_table; + +#ifdef FEATURE_FOURTH_CONNECTION +extern const enum policy_mgr_pcl_type + fourth_connection_pcl_dbs_table + [PM_MAX_THREE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE]; +#endif + extern policy_mgr_next_action_two_connection_table_type *next_action_two_connection_2x2_2g_1x1_5g_table; extern policy_mgr_next_action_three_connection_table_type 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 f9dee88e23f7..7abb7baf0353 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 @@ -628,6 +628,48 @@ static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl( return status; } +#ifdef FEATURE_FOURTH_CONNECTION +static enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + enum policy_mgr_conc_priority_mode pref) +{ + enum policy_mgr_three_connection_mode fourth_index = 0; + enum policy_mgr_pcl_type pcl; + + /* Will be enhanced for other types of 4 port conc (NaN etc.) + * in future. + */ + if (mode != PM_STA_MODE && mode != PM_SAP_MODE) { + policy_mgr_err("Can't start 4th port if not STA, SAP"); + return PM_MAX_PCL_TYPE; + } + + fourth_index = + policy_mgr_get_fourth_connection_pcl_table_index(psoc); + if (PM_MAX_THREE_CONNECTION_MODE == fourth_index) { + policy_mgr_err("Can't find index for 4th port pcl table"); + return PM_MAX_PCL_TYPE; + } + policy_mgr_debug("Index for 4th port pcl table: %d", fourth_index); + + if (policy_mgr_is_hw_dbs_capable(psoc) == true) { + pcl = fourth_connection_pcl_dbs_table + [fourth_index][mode][pref]; + return pcl; + } + policy_mgr_err("Can't find index for 4th port pcl table for non dbs capable"); + + return PM_MAX_PCL_TYPE; +} +#else +static inline enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + enum policy_mgr_conc_priority_mode pref) +{return PM_MAX_PCL_TYPE; } +#endif + QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t *pcl_channels, uint32_t *len, @@ -718,6 +760,9 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, [third_index][mode][conc_system_pref]; } break; + case 3: + pcl = policy_mgr_get_pcl_4_port(psoc, mode, conc_system_pref); + break; default: policy_mgr_err("unexpected num_connections value %d", num_connections); @@ -1657,6 +1702,127 @@ enum policy_mgr_two_connection_mode return index; } +#ifdef FEATURE_FOURTH_CONNECTION +enum policy_mgr_three_connection_mode + policy_mgr_get_fourth_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc) +{ + enum policy_mgr_three_connection_mode index = + PM_MAX_THREE_CONNECTION_MODE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t count_sap = 0; + uint32_t count_sta = 0; + uint32_t list_sap[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t list_sta[MAX_NUMBER_OF_CONC_CONNECTIONS]; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return index; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + + /* For 4 port concurrency case, + * 1st step: (SAP+STA) (2.4G MAC SCC)+(SAP+STA) (5G MAC SCC) + */ + count_sap += policy_mgr_mode_specific_connection_count( + psoc, PM_SAP_MODE, &list_sap[count_sap]); + count_sta = policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, list_sta); + policy_mgr_debug("sap/ago num: %d, sta num: %d", count_sap, count_sta); + if (count_sap == 2 && count_sta == 1) { + policy_mgr_debug( + "channel: sap0: %d, sap1: %d, sta0: %d", + pm_conc_connection_list[list_sap[0]].chan, + pm_conc_connection_list[list_sap[1]].chan, + pm_conc_connection_list[list_sta[0]].chan); + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sap[0]].chan) && + WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sta[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sap[1]].chan)) { + index = PM_STA_SAP_SCC_24_SAP_5_DBS; + } else if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sap[1]].chan) && + WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sta[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sap[0]].chan)) { + index = PM_STA_SAP_SCC_24_SAP_5_DBS; + } else if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sap[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sta[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sap[1]].chan)) { + index = PM_STA_SAP_SCC_5_SAP_24_DBS; + } else if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sap[1]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sta[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sap[0]].chan)) { + index = PM_STA_SAP_SCC_5_SAP_24_DBS; + } else { + index = PM_MAX_THREE_CONNECTION_MODE; + } + } else if (count_sap == 1 && count_sta == 2) { + policy_mgr_debug( + "channel: sap0: %d, sta0: %d, sta1: %d", + pm_conc_connection_list[list_sap[0]].chan, + pm_conc_connection_list[list_sta[0]].chan, + pm_conc_connection_list[list_sta[1]].chan); + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sta[0]].chan) && + WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sap[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sta[1]].chan)) { + index = PM_STA_SAP_SCC_24_STA_5_DBS; + } else if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sta[1]].chan) && + WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sap[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sta[0]].chan)) { + index = PM_STA_SAP_SCC_24_STA_5_DBS; + } else if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sta[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sap[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sta[1]].chan)) { + index = PM_STA_SAP_SCC_5_STA_24_DBS; + } else if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list_sta[1]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sap[0]].chan) && + WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list_sta[0]].chan)) { + index = PM_STA_SAP_SCC_5_STA_24_DBS; + } else { + index = PM_MAX_THREE_CONNECTION_MODE; + } + } + + policy_mgr_debug( + "mode0:%d mode1:%d mode2:%d chan0:%d chan1:%d chan2:%d chain:%d index:%d", + pm_conc_connection_list[0].mode, + pm_conc_connection_list[1].mode, + pm_conc_connection_list[2].mode, + pm_conc_connection_list[0].chan, + pm_conc_connection_list[1].chan, + pm_conc_connection_list[2].chan, + pm_conc_connection_list[0].chain_mask, index); + + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return index; +} +#endif + uint8_t policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h index 8bf0f8647ddd..edabbae6c30e 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -1882,6 +1882,27 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, }; +#ifdef FEATURE_FOURTH_CONNECTION +/** + * fourth_connection_pcl_dbs_table - table which provides PCL for + * the 4th connection, when we have 3 connections already in + * the system (with DBS supported by HW) + */ +const enum policy_mgr_pcl_type +fourth_connection_pcl_dbs_table + [PM_MAX_THREE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE] = { + [PM_STA_SAP_SCC_24_SAP_5_DBS] = { + [PM_STA_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_STA_SAP_SCC_5_SAP_24_DBS] = { + [PM_STA_MODE] = { PM_24G, PM_24G, PM_24G } }, + [PM_STA_SAP_SCC_24_STA_5_DBS] = { + [PM_SAP_MODE] = { PM_5G, PM_5G, PM_5G } }, + [PM_STA_SAP_SCC_5_STA_24_DBS] = { + [PM_SAP_MODE] = { PM_24G, PM_24G, PM_24G } } +}; +#endif + /** * next_action_two_connection_table - table which provides next * action while a new connection is coming up, with one