From da1d4517f482e9183fdf4cc6e879255d60c5ca4a Mon Sep 17 00:00:00 2001 From: Zhu Jianmin Date: Thu, 19 Apr 2018 17:55:30 +0800 Subject: [PATCH] qcacmn: Check chip capability when enable AP+AP Check capability of dbs, mcc and scc on single band when enable AP+AP, then same driver code can support different chip and firmware. Add wmi_service_dual_beacon_on_single_mac_(mcc/scc)_support Change-Id: I505747122504b2a89813e7bdfcd27dc07539f39e CRs-Fixed: 2214237 --- .../policy_mgr/inc/wlan_policy_mgr_api.h | 35 ++++++ .../src/wlan_policy_mgr_get_set_utils.c | 119 ++++++++++++++++++ wmi/inc/wmi_unified_param.h | 2 + wmi/src/wmi_unified_tlv.c | 10 ++ 4 files changed, 166 insertions(+) diff --git a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 38c84cb7cff2..22e1f7b38ee8 100644 --- a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -2297,4 +2297,39 @@ QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_allow_sap_go_concurrency() - check whether multiple SAP/GO + * interfaces are allowed + * @psoc: pointer to soc + * @policy_mgr_con_mode: operating mode of the new interface + * @channel: operating channel of the new interface + * This function checks whether second SAP/GO interface is allowed on the same + * MAC. + * + * Return: true or false + */ +bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel); + +/** + * policy_mgr_dual_beacon_on_single_mac_scc_capable() - get capability that + * whether support dual beacon on same channel on single MAC + * @psoc: pointer to soc + * + * Return: bool: capable + */ +bool policy_mgr_dual_beacon_on_single_mac_scc_capable( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_dual_beacon_on_single_mac_mcc_capable() - get capability that + * whether support dual beacon on different channel on single MAC + * @psoc: pointer to soc + * + * Return: bool: capable + */ +bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( + struct wlan_objmgr_psoc *psoc); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index a8df535e0761..68f87c0a6dce 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -1693,6 +1693,11 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, } } + if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, channel)) { + policy_mgr_err("This concurrency combination is not allowed"); + goto done; + } + /* don't allow two P2P GO on same band */ if (channel && (mode == PM_P2P_GO_MODE) && num_connections) { index = 0; @@ -2950,3 +2955,117 @@ uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, return count; } + +bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel) +{ + uint32_t sap_cnt; + uint32_t go_cnt; + enum policy_mgr_con_mode con_mode; + uint8_t con_chan; + int id; + + sap_cnt = policy_mgr_mode_specific_connection_count(psoc, + PM_SAP_MODE, + NULL); + go_cnt = policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_GO_MODE, + NULL); + + if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) && + (sap_cnt || go_cnt)) { + if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc)) + return true; + if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc)) { + for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; + id++) { + if (pm_conc_connection_list[id].in_use) { + con_mode = + pm_conc_connection_list[id].mode; + con_chan = + pm_conc_connection_list[id].chan; + if (((con_mode == PM_SAP_MODE) || + (con_mode == PM_P2P_GO_MODE)) && + (channel != con_chan)) { + policy_mgr_debug("Scc is supported, but first SAP and second SAP are not in same channel, So don't allow second SAP interface"); + return false; + } + } + } + return true; + } + if (!policy_mgr_is_hw_dbs_capable(psoc)) { + policy_mgr_debug("DBS is not supported, mcc and scc are not supported too, don't allow second SAP interface"); + return false; + } + /* If DBS is supported then allow second SAP/GO session only if + * the freq band of the second SAP/GO interface is different + * than the first SAP/GO interface. + */ + for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) { + if (pm_conc_connection_list[id].in_use) { + con_mode = pm_conc_connection_list[id].mode; + con_chan = pm_conc_connection_list[id].chan; + if (((con_mode == PM_SAP_MODE) || + (con_mode == PM_P2P_GO_MODE)) && + (WLAN_REG_IS_SAME_BAND_CHANNELS(channel, + con_chan))) { + policy_mgr_debug("DBS is supported, but first SAP and second SAP are on same band, So don't allow second SAP interface"); + return false; + } + } + } + } + + /* Don't block the second interface */ + return true; +} + +bool policy_mgr_dual_beacon_on_single_mac_scc_capable( + struct wlan_objmgr_psoc *psoc) +{ + void *wmi_handle = NULL; + + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + if (!wmi_handle) { + policy_mgr_debug("Invalid WMI handle"); + return false; + } + + if (wmi_service_enabled( + wmi_handle, + wmi_service_dual_beacon_on_single_mac_scc_support)) { + policy_mgr_debug("Support dual beacon on same channel on single MAC"); + return true; + } + if (wmi_service_enabled( + wmi_handle, + wmi_service_dual_beacon_on_single_mac_mcc_support)) { + policy_mgr_debug("Support dual beacon on both different and same channel on single MAC"); + return true; + } + policy_mgr_debug("Not support dual beacon on same channel on single MAC"); + return false; +} + +bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( + struct wlan_objmgr_psoc *psoc) +{ + void *wmi_handle = NULL; + + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + if (!wmi_handle) { + policy_mgr_debug("Invalid WMI handle"); + return false; + } + + if (wmi_service_enabled( + wmi_handle, + wmi_service_dual_beacon_on_single_mac_mcc_support)) { + policy_mgr_debug("Support dual beacon on different channel on single MAC"); + return true; + } + policy_mgr_debug("Not support dual beacon on different channel on single MAC"); + return false; +} diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 5bd23e6d651d..dd76ac48ec5f 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -5951,6 +5951,8 @@ typedef enum { wmi_service_bss_color_offload, wmi_service_gmac_offload_support, wmi_service_host_dfs_check_support, + wmi_service_dual_beacon_on_single_mac_scc_support, + wmi_service_dual_beacon_on_single_mac_mcc_support, wmi_services_max, } wmi_conv_service_ids; diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 2211dd6667a4..6fc7dedf2b7d 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -18019,6 +18019,12 @@ static bool is_service_enabled_tlv(wmi_unified_t wmi_handle, soc->wmi_ext_service_bitmap, service_id); + if (service_id >= WMI_MAX_SERVICE) { + WMI_LOGE("Service id %d but WMI ext service bitmap is NULL", + service_id); + return false; + } + return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap, service_id); } @@ -23559,6 +23565,10 @@ static void populate_tlv_service(uint32_t *wmi_service) WMI_SERVICE_BSS_COLOR_OFFLOAD; wmi_service[wmi_service_gmac_offload_support] = WMI_SERVICE_GMAC_OFFLOAD_SUPPORT; + wmi_service[wmi_service_dual_beacon_on_single_mac_scc_support] = + WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_SCC_SUPPORT; + wmi_service[wmi_service_dual_beacon_on_single_mac_mcc_support] = + WMI_SERVICE_DUAL_BEACON_ON_SINGLE_MAC_MCC_SUPPORT; }