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 7dcf9950e5f3..1716caa948dc 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 @@ -2794,6 +2794,17 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, uint8_t channel, uint32_t vdev_id); +/** + * policy_mgr_allow_multiple_sta_connections() - API to get FW support + * @psoc: Pointer to soc + * + * This function checks FW support for simultaneous connections on + * concurrent STA interfaces. + * + * Return: true if supports else false. + */ +bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_dual_beacon_on_single_mac_scc_capable() - get capability that * whether support dual beacon on same channel on single MAC 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 a007f442e39c..fa0ac047a321 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 @@ -1981,14 +1981,22 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, } } + count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, + list); + + /* Check for STA+STA concurrency */ + if (mode == PM_STA_MODE && count && + !policy_mgr_allow_multiple_sta_connections(psoc)) { + policy_mgr_err("No 2nd STA connection, already one STA is connected"); + goto done; + } + /* * Check all IBSS+STA concurrencies * * don't allow IBSS + STA MCC * don't allow IBSS + STA SCC if IBSS is on DFS channel */ - count = policy_mgr_mode_specific_connection_count(psoc, - PM_STA_MODE, list); if ((PM_IBSS_MODE == mode) && (policy_mgr_mode_specific_connection_count(psoc, PM_IBSS_MODE, list)) && count) { @@ -3414,6 +3422,24 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, return true; } +bool policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc) +{ + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + policy_mgr_debug("Invalid WMI handle"); + return false; + } + + if (wmi_service_enabled(wmi_handle, + wmi_service_sta_plus_sta_support)) + return true; + + policy_mgr_debug("Concurrent STA connections are not supported"); + return false; +} + bool policy_mgr_dual_beacon_on_single_mac_scc_capable( struct wlan_objmgr_psoc *psoc) { diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index d7591ceeb3d7..a0685b6614b0 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -14090,32 +14090,6 @@ static int wlan_hdd_cfg80211_change_bss(struct wiphy *wiphy, return errno; } -/** - * hdd_nl_to_policy_mgr_iface_type() - map nl80211_iftype to policy_mgr_con_mode - * @type: the input NL80211 interface type to map - * - * Return: policy_mgr_con_mode - */ -static enum policy_mgr_con_mode -hdd_nl_to_policy_mgr_iface_type(enum nl80211_iftype type) -{ - switch (type) { - case NL80211_IFTYPE_STATION: - return PM_STA_MODE; - case NL80211_IFTYPE_P2P_CLIENT: - return PM_P2P_CLIENT_MODE; - case NL80211_IFTYPE_P2P_GO: - return PM_P2P_GO_MODE; - case NL80211_IFTYPE_AP: - return PM_SAP_MODE; - case NL80211_IFTYPE_ADHOC: - return PM_IBSS_MODE; - default: - hdd_err("Unsupported interface type: %d", type); - return PM_MAX_NUM_OF_MODE; - } -} - static bool hdd_is_client_mode(enum QDF_OPMODE mode) { switch (mode) { @@ -14204,13 +14178,6 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, return -EINVAL; } - if (!policy_mgr_allow_concurrency(hdd_ctx->psoc, - hdd_nl_to_policy_mgr_iface_type(type), - 0, HW_MODE_20_MHZ)) { - hdd_debug("This concurrency combination is not allowed"); - return -EINVAL; - } - /* Reset the current device mode bit mask */ policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode); diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 9292e43da59e..135699ac1f42 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -5593,6 +5593,43 @@ csr_roam_trigger_reassociate(struct mac_context *mac_ctx, tSmeCmd *cmd, return status; } +/** + * csr_allow_concurrent_sta_connections() - Wrapper for policy_mgr api + * @mac: mac context + * @vdev_id: vdev id + * + * This function invokes policy mgr api to check for support of + * simultaneous connections on concurrent STA interfaces. + * + * Return: If supports return true else false. + */ +static +bool csr_allow_concurrent_sta_connections(struct mac_context *mac, + uint32_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + enum QDF_OPMODE vdev_mode; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, + WLAN_LEGACY_MAC_ID); + if (!vdev) { + sme_err("vdev object not found for vdev_id %u", vdev_id); + return false; + } + vdev_mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + + /* If vdev mode is STA then proceed further */ + if (vdev_mode != QDF_STA_MODE) + return true; + + if (policy_mgr_allow_concurrency(mac->psoc, PM_STA_MODE, 0, + HW_MODE_20_MHZ)) + return true; + + return false; +} + QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand) { QDF_STATUS lock_status, status = QDF_STATUS_SUCCESS; @@ -5705,6 +5742,21 @@ QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand) status = csr_roam_issue_ft_preauth_req(mac, sessionId, pCommand->u.roamCmd.pLastRoamBss); break; + + case eCsrHddIssued: + /* + * Check for simultaneous connection support on + * multiple STA interfaces. + */ + if (!csr_allow_concurrent_sta_connections(mac, sessionId)) { + sme_err("No support of conc STA con"); + csr_roam_complete(mac, eCsrNothingToJoin, NULL, + sessionId); + status = QDF_STATUS_E_FAILURE; + break; + } + /* Fall through for success case */ + default: csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, sessionId);