Explorar o código

qcacld-3.0: Avoid NSS and Antenna mode change during TDLS connection

In the api hdd_set_nss_params() and hdd_set_antenna_mode()
change in nss parameter or antenna mode cause the TDLS
teardown.

Add a check in api hdd_set_nss_params() and
hdd_set_antenna_mode() to prevent change in parameter
if there is a existing TDLS connection.

Change-Id: I8a58b8b0a617a8de490907e4c3181b15d90e0dbb
CRs-Fixed: 3789892
Vijay Raj hai 1 ano
pai
achega
847c26d19d

+ 10 - 1
components/tdls/dispatcher/inc/wlan_tdls_api.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 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 above
@@ -104,6 +104,15 @@ wlan_tdls_notify_sta_connect(uint8_t vdev_id,
 			     bool tdls_prohibited,
 			     struct wlan_objmgr_vdev *vdev);
 
+/**
+ * wlan_is_tdls_session_present() - Get TDLS session status
+ * @vdev: vdev pointer
+ *
+ * Return: QDF_STATUS_SUCCESS if success; other value if failed
+ */
+QDF_STATUS
+wlan_is_tdls_session_present(struct wlan_objmgr_vdev *vdev);
+
 /**
  * wlan_tdls_update_tx_pkt_cnt() - update tx pkt count
  * @vdev: tdls vdev object

+ 45 - 0
components/tdls/dispatcher/src/wlan_tdls_api.c

@@ -31,6 +31,7 @@
 #include <wlan_objmgr_cmn.h>
 #include "wlan_tdls_cfg_api.h"
 #include "wlan_policy_mgr_api.h"
+#include "wlan_mlo_mgr_sta.h"
 
 static QDF_STATUS tdls_teardown_flush_cb(struct scheduler_msg *msg)
 {
@@ -286,6 +287,50 @@ wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc *psoc)
 {}
 #endif
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static QDF_STATUS
+wlan_mlo_is_tdls_session_present(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t i;
+	struct wlan_mlo_dev_context *ml_dev = vdev->mlo_dev_ctx;
+
+	if (!ml_dev) {
+		tdls_err("MLO dev ctx is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < ml_dev->wlan_vdev_count; i++) {
+		vdev = ml_dev->wlan_vdev_list[i];
+		if (tdls_get_connected_peer_count_from_vdev(vdev) > 0) {
+			tdls_debug("TDLS session is present");
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	return QDF_STATUS_E_INVAL;
+}
+#else
+static QDF_STATUS
+wlan_mlo_is_tdls_session_present(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_E_INVAL;
+}
+#endif
+
+QDF_STATUS
+wlan_is_tdls_session_present(struct wlan_objmgr_vdev *vdev)
+{
+	if (mlo_is_mld_sta(vdev))
+		return wlan_mlo_is_tdls_session_present(vdev);
+
+	if (tdls_get_connected_peer_count_from_vdev(vdev) > 0) {
+		tdls_debug("TDLS session is present");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return QDF_STATUS_E_INVAL;
+}
+
 void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc,
 				struct wlan_objmgr_vdev *vdev)
 {

+ 8 - 0
core/hdd/src/wlan_hdd_ioctl.c

@@ -50,6 +50,7 @@
 #include "wlan_reg_ucfg_api.h"
 #include "qdf_func_tracker.h"
 #include "wlan_cm_roam_ucfg_api.h"
+#include "wlan_tdls_api.h"
 
 #if defined(LINUX_QCMBR)
 #define SIOCIOCTLTX99 (SIOCDEVPRIVATE+13)
@@ -6063,6 +6064,13 @@ int hdd_set_antenna_mode(struct wlan_hdd_link_info *link_info, int mode)
 		.timeout_ms = SME_POLICY_MGR_CMD_TIMEOUT,
 	};
 
+	if (QDF_STATUS_SUCCESS ==
+	    wlan_is_tdls_session_present(link_info->vdev)) {
+		hdd_debug("TDLS session exists");
+		ret = -EINVAL;
+		goto exit;
+	}
+
 	switch (mode) {
 	case HDD_ANTENNA_MODE_1X1:
 		params.num_rx_chains = 1;

+ 9 - 2
core/sme/src/common/sme_api.c

@@ -89,6 +89,7 @@
 #include "wlan_policy_mgr_ll_sap.h"
 #include "wlan_vdev_mgr_ucfg_api.h"
 #include "wlan_vdev_mlme_main.h"
+#include "wlan_tdls_api.h"
 
 static QDF_STATUS init_sme_cmd_list(struct mac_context *mac);
 
@@ -4780,7 +4781,7 @@ sme_nss_chains_update(mac_handle_t mac_handle,
 		      uint8_t vdev_id)
 {
 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
-	QDF_STATUS status;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	struct wlan_mlme_nss_chains *dynamic_cfg;
 	struct wlan_objmgr_vdev *vdev =
 		       wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
@@ -4798,7 +4799,13 @@ sme_nss_chains_update(mac_handle_t mac_handle,
 	if (ll_lt_sap_vdev_id != WLAN_INVALID_VDEV_ID) {
 		sme_info_rl("LL_LT_SAP vdev %d present, chainmask config not allowed",
 			    ll_lt_sap_vdev_id);
-		return QDF_STATUS_E_FAILURE;
+		goto release_ref;
+	}
+
+	if (QDF_STATUS_SUCCESS == wlan_is_tdls_session_present(vdev)) {
+		sme_debug("TDLS session exists");
+		status = QDF_STATUS_E_FAILURE;
+		goto release_ref;
 	}
 
 	status = sme_acquire_global_lock(&mac_ctx->sme);