From 37a1c90ea328fc82c5af45ff429962b1845cf795 Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Wed, 8 Feb 2023 03:53:48 +0530 Subject: [PATCH] qcacld-3.0: Add initial checks for TDLS concurrencies Check if TDLS is allowed for the current existing concurrency combination. In below combinations, TDLS is not allowed: 1. MCC on STA vdev 2. STA + STA 3. Total connection count > 3 4. No STA vdev exists If existing TDLS connection exists when 4th port is coming up, then teardown the TDLS connection and disable off channel. Change-Id: Iabe174bedecfa6147bd9de3cb2a3716b63145456 CRs-Fixed: 3435864 --- .../tdls/core/src/wlan_tdls_cmds_process.c | 9 +- components/tdls/core/src/wlan_tdls_main.c | 181 ++++++++++-------- components/tdls/core/src/wlan_tdls_main.h | 22 ++- .../dispatcher/inc/wlan_tdls_public_structs.h | 2 +- 4 files changed, 128 insertions(+), 86 deletions(-) diff --git a/components/tdls/core/src/wlan_tdls_cmds_process.c b/components/tdls/core/src/wlan_tdls_cmds_process.c index e9539fc24a..8e4e962407 100644 --- a/components/tdls/core/src/wlan_tdls_cmds_process.c +++ b/components/tdls/core/src/wlan_tdls_cmds_process.c @@ -1966,10 +1966,7 @@ static QDF_STATUS tdls_config_force_peer( req->op_class, req->min_bandwidth); tdls_set_callback(peer, req->callback); - - tdls_set_ct_mode(soc_obj->soc); - if (soc_obj->enable_tdls_connection_tracker) - tdls_implicit_enable(vdev_obj); + tdls_set_ct_mode(soc_obj->soc, vdev); return status; error: @@ -2146,9 +2143,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) qdf_mem_free(peer_update_param); goto error; } - tdls_set_ct_mode(soc_obj->soc); - if (!soc_obj->enable_tdls_connection_tracker) - tdls_implicit_disable(vdev_obj); + tdls_set_ct_mode(soc_obj->soc, vdev); error: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); diff --git a/components/tdls/core/src/wlan_tdls_main.c b/components/tdls/core/src/wlan_tdls_main.c index f28a2686d0..e3c5806ebe 100644 --- a/components/tdls/core/src/wlan_tdls_main.c +++ b/components/tdls/core/src/wlan_tdls_main.c @@ -958,6 +958,7 @@ bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev) bool state = false; qdf_freq_t ch_freq; QDF_STATUS status; + uint32_t connection_count; status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) @@ -979,14 +980,22 @@ bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev) goto exit; } - if (policy_mgr_get_connection_count(tdls_soc_obj->soc) == 1) + connection_count = policy_mgr_get_connection_count(tdls_soc_obj->soc); + if (connection_count == 1 || + (connection_count > 1 && + tdls_is_concurrency_allowed(tdls_soc_obj->soc))) { state = true; - else + } else { tdls_warn("Concurrent sessions exist disable TDLS"); + goto exit; + } ch_freq = wlan_get_operation_chan_freq(vdev); - if (wlan_reg_is_6ghz_chan_freq(ch_freq)) - state &= tdls_is_6g_freq_allowed(vdev, ch_freq); + if (wlan_reg_is_6ghz_chan_freq(ch_freq) && + !tdls_is_6g_freq_allowed(vdev, ch_freq)) { + tdls_debug("6GHz freq:%d not allowed for TDLS", ch_freq); + state = false; + } exit: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); @@ -994,72 +1003,105 @@ exit: return state; } -/** - * tdls_set_ct_mode() - Set the tdls connection tracker mode - * @psoc: psoc context - * - * This routine is called to set the tdls connection tracker operation status - * - * Return: NONE - */ -void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc) +#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES +bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc) { - bool state = false; - struct tdls_soc_priv_obj *tdls_soc_obj; + if (!wlan_psoc_nif_fw_ext2_cap_get(psoc, + WLAN_TDLS_CONCURRENCIES_SUPPORT)) + return false; - tdls_soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); - if (!tdls_soc_obj) + if (policy_mgr_get_connection_count(psoc) > + WLAN_TDLS_MAX_CONCURRENT_VDEV_SUPPORTED) + return false; + + if (policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, + NULL) > 1) { + tdls_debug("More than one STA exist. Don't allow TDLS"); + return false; + } + + if (policy_mgr_current_concurrency_is_mcc(psoc)) { + tdls_debug("Base channel MCC. Don't allow TDLS"); + return false; + } + + /* + * Don't enable TDLS for P2P_CLI in concurrency cases + */ + if (policy_mgr_get_connection_count(psoc) > 1 && + !policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, + NULL)) + return false; + + return true; +} +#endif + +void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev) +{ + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + uint32_t tdls_feature_flags = 0, sta_count, p2p_count; + bool state = false; + QDF_STATUS status; + + if (!tdls_check_is_tdls_allowed(vdev)) return; - /* If any concurrency is detected, skip tdls pkt tracker */ - if (policy_mgr_get_connection_count(psoc) > 1) { + status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to get TDLS objects"); state = false; goto set_state; } + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; if (TDLS_SUPPORT_DISABLED == tdls_soc_obj->tdls_current_mode || TDLS_SUPPORT_SUSPENDED == tdls_soc_obj->tdls_current_mode || - !TDLS_IS_IMPLICIT_TRIG_ENABLED( - tdls_soc_obj->tdls_configs.tdls_feature_flags)) { - state = false; - goto set_state; - } else if (policy_mgr_mode_specific_connection_count(psoc, - PM_STA_MODE, - NULL) == 1) { - state = true; - } else if (policy_mgr_mode_specific_connection_count(psoc, - PM_P2P_CLIENT_MODE, - NULL) == 1){ - state = true; - } else { + !TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) { state = false; goto set_state; } - /* In case of TDLS external control, peer should be added - * by the user space to start connection tracker. - */ - if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( - tdls_soc_obj->tdls_configs.tdls_feature_flags)) { - if (tdls_soc_obj->tdls_external_peer_count) - state = true; - else + sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, + NULL); + p2p_count = + policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_CLIENT_MODE, + NULL); + if (sta_count == 1 || + (policy_mgr_get_connection_count(psoc) == 1 && p2p_count == 1)) { + state = true; + /* + * In case of TDLS external control, peer should be added + * by the user space to start connection tracker. + */ + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags) && + !tdls_soc_obj->tdls_external_peer_count) state = false; + + goto set_state; } + state = false; + set_state: tdls_soc_obj->enable_tdls_connection_tracker = state; + if (tdls_soc_obj->enable_tdls_connection_tracker) + tdls_implicit_enable(tdls_vdev_obj); + else + tdls_implicit_disable(tdls_vdev_obj); - tdls_debug("enable_tdls_connection_tracker %d", - tdls_soc_obj->enable_tdls_connection_tracker); + tdls_debug("enable_tdls_connection_tracker %d current_mode:%d feature_flags:0x%x", + tdls_soc_obj->enable_tdls_connection_tracker, + tdls_soc_obj->tdls_current_mode, tdls_feature_flags); } QDF_STATUS tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) { - struct tdls_vdev_priv_obj *tdls_priv_vdev; struct wlan_objmgr_vdev *tdls_obj_vdev; - struct tdls_soc_priv_obj *tdls_priv_soc; if (!psoc) { tdls_err("psoc: %pK", psoc); @@ -1078,11 +1120,7 @@ tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) } tdls_debug("enter "); - tdls_set_ct_mode(psoc); - if (tdls_get_vdev_objects(tdls_obj_vdev, &tdls_priv_vdev, - &tdls_priv_soc) == QDF_STATUS_SUCCESS && - tdls_priv_soc->enable_tdls_connection_tracker) - tdls_implicit_enable(tdls_priv_vdev); + tdls_set_ct_mode(psoc, tdls_obj_vdev); wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID); @@ -1137,21 +1175,23 @@ struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, { uint32_t vdev_id; - if (policy_mgr_get_connection_count(psoc) > 1) + if (policy_mgr_get_connection_count(psoc) > 1 && + !tdls_is_concurrency_allowed(psoc)) return NULL; vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE); - if (WLAN_INVALID_VDEV_ID != vdev_id) - return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, - vdev_id, + return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, dbg_id); - + /* + * For P2P_Client mode, TDLS is not supported on concurrency + * so return P2P_client vdev only if P2P client mode exists without + * any concurreny + */ vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_P2P_CLIENT_MODE); - - if (WLAN_INVALID_VDEV_ID != vdev_id) - return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, - vdev_id, + if (WLAN_INVALID_VDEV_ID != vdev_id && + policy_mgr_get_connection_count(psoc) == 1) + return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, dbg_id); return NULL; @@ -1369,9 +1409,7 @@ tdls_process_sta_connect(struct tdls_sta_notify_params *notify) notify->session_id); /* check and set the connection tracker */ - tdls_set_ct_mode(tdls_soc_obj->soc); - if (tdls_soc_obj->enable_tdls_connection_tracker) - tdls_implicit_enable(tdls_vdev_obj); + tdls_set_ct_mode(tdls_soc_obj->soc, notify->vdev); return QDF_STATUS_SUCCESS; } @@ -1458,16 +1496,11 @@ tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify) } /* Check and set the connection tracker and implicit timers */ - tdls_set_ct_mode(curr_tdls_soc->soc); - if (curr_tdls_soc->enable_tdls_connection_tracker) - tdls_implicit_enable(curr_tdls_vdev); - else - tdls_implicit_disable(curr_tdls_vdev); - - /* release the vdev ref , if temp vdev was acquired */ - if (temp_vdev) + if (temp_vdev) { + tdls_set_ct_mode(curr_tdls_soc->soc, temp_vdev); wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_TDLS_NB_ID); + } return status; } @@ -1657,18 +1690,15 @@ static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev, /* If tdls implicit mode is disabled, then * stop the connection tracker. */ - tdls_soc->enable_tdls_connection_tracker = - false; - } else if (TDLS_SUPPORT_EXP_TRIG_ONLY == - tdls_mode) { + tdls_soc->enable_tdls_connection_tracker = false; + } else if (TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_mode) { clear_bit((unsigned long)source, &tdls_soc->tdls_source_bitmap); tdls_implicit_disable(tdls_vdev); /* If tdls implicit mode is disabled, then * stop the connection tracker. */ - tdls_soc->enable_tdls_connection_tracker = - false; + tdls_soc->enable_tdls_connection_tracker = false; /* * Check if any TDLS source bit is set and if @@ -1679,7 +1709,6 @@ static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev, return; } tdls_debug("exit "); - } /** diff --git a/components/tdls/core/src/wlan_tdls_main.h b/components/tdls/core/src/wlan_tdls_main.h index 9fe28d2bbd..ad12b9b4ed 100644 --- a/components/tdls/core/src/wlan_tdls_main.h +++ b/components/tdls/core/src/wlan_tdls_main.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -566,12 +566,14 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, /** * tdls_set_ct_mode() - Set the tdls connection tracker mode * @psoc: objmgr psoc object + * @vdev: Pointer to vdev object * * This routine is called to set the tdls connection tracker operation status * * Return: NONE */ -void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc); +void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev); /** * tdls_set_operation_mode() - set tdls operating mode @@ -825,4 +827,20 @@ QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, uint8_t tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev *vdev, qdf_freq_t freq, uint8_t bw_offset, uint8_t *reg_bw_offset); + +#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES +/** + * tdls_is_concurrency_allowed() - Is TDLS allowed with the current concurrency + * @psoc: Pointer to PSOC + * + * Return: True or False + */ +bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc); +#else +static inline bool +tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc) +{ + return false; +} +#endif /* WLAN_FEATURE_TDLS_CONCURRENCIES */ #endif diff --git a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h index 527a13d38a..305042af38 100644 --- a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -54,7 +54,7 @@ #define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165 #define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF 36 #define WLAN_TDLS_PREFERRED_OFF_CHANNEL_FRQ_DEF 5180 - +#define WLAN_TDLS_MAX_CONCURRENT_VDEV_SUPPORTED 3 #define AC_PRIORITY_NUM 4