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
This commit is contained in:

zatwierdzone przez
Madan Koyyalamudi

rodzic
c92b309cfa
commit
37a1c90ea3
@@ -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);
|
||||
|
@@ -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 ");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user