Browse Source

qcacld-3.0: Reject TDLS when ML STA links are on MCC

When ML STA links are on MCC, TDLS action frames try to
set the link mode to force active. To avoid this
reject the TDLS mgmt request when ML STA links are on MCC.

Also enhance few debug prints for TDLS.

CRs-Fixed: 3717831
Change-Id: I69a942d80f5fac0ff25cfb47229e5dde6a693f97
Pragaspathi Thilagaraj 1 year ago
parent
commit
fbda9a4e96

+ 16 - 1
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -4829,7 +4829,7 @@ bool policy_mgr_is_mlo_sta_disconnected(struct wlan_objmgr_psoc *psoc,
 					uint8_t vdev_id);
 
 #ifdef WLAN_FEATURE_11BE_MLO
-/*
+/**
  * policy_mgr_is_ml_sta_links_in_mcc() - Check ML links are in MCC or not
  * @psoc: psoc ctx
  * @ml_freq_lst: ML STA freq list
@@ -4849,6 +4849,21 @@ policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc *psoc,
 				  uint8_t num_ml_sta,
 				  uint32_t *affected_linkid_bitmap);
 
+/**
+ * policy_mgr_is_ml_links_in_mcc_allowed() - Check ML links are in MCC or not
+ * @psoc: psoc ctx
+ * @vdev: Pointer to vdev object
+ * @ml_sta_vdev_lst: ML STA vdev id list
+ * @num_ml_sta: Number of total ML STA links
+ *
+ * Return: QDF_STATUS_SUCCESS if ML link in MCC is allowed
+ */
+QDF_STATUS
+policy_mgr_is_ml_links_in_mcc_allowed(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      uint8_t *ml_sta_vdev_lst,
+				      uint8_t *num_ml_sta);
+
 /**
  * policy_mgr_is_vdev_high_tput_or_low_latency() - Check vdev has
  * high througput or low latency flag

+ 40 - 20
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -7752,37 +7752,26 @@ policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc *psoc,
 	return false;
 }
 
-/*
- * policy_mgr_handle_mcc_ml_sta() - disables one ML STA link if causing MCC
- * DBS - if ML STA links on 5 GHz + 6 GHz
- * SBS - if both ML STA links on 5 GHz high/5 GHz low
- * non-SBS - any combo (5/6 GHz + 5/6 GHz OR 2 GHz + 5/6 GHz)
- * @psoc: psoc ctx
- *
- * Return: Success if MCC link is disabled else failure
- */
-static QDF_STATUS
-policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
-			     struct wlan_objmgr_vdev *vdev)
+QDF_STATUS
+policy_mgr_is_ml_links_in_mcc_allowed(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_objmgr_vdev *vdev,
+				      uint8_t *ml_sta_vdev_lst,
+				      uint8_t *num_ml_sta)
 {
-	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
-	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	uint8_t num_disabled_ml_sta = 0;
 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 
-	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE))
-		return QDF_STATUS_E_FAILURE;
-
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
 		policy_mgr_err("Invalid Context");
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
+	policy_mgr_get_ml_sta_info(pm_ctx, num_ml_sta, &num_disabled_ml_sta,
 				   ml_sta_vdev_lst, ml_freq_lst,
 				   NULL, NULL, NULL);
-	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
+	if (*num_ml_sta < 2 || *num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
 	    num_disabled_ml_sta) {
 		policy_mgr_debug("num_ml_sta invalid %d or link already disabled%d",
 				 num_ml_sta, num_disabled_ml_sta);
@@ -7791,7 +7780,7 @@ policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
 
 	if (!policy_mgr_is_ml_sta_links_in_mcc(psoc, ml_freq_lst,
 					       ml_sta_vdev_lst, NULL,
-					       num_ml_sta,
+					       *num_ml_sta,
 					       NULL))
 		return QDF_STATUS_E_FAILURE;
 
@@ -7804,9 +7793,40 @@ policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * policy_mgr_handle_mcc_ml_sta() - disables one ML STA link if causing MCC
+ * DBS - if ML STA links on 5 GHz + 6 GHz
+ * SBS - if both ML STA links on 5 GHz high/5 GHz low
+ * non-SBS - any combo (5/6 GHz + 5/6 GHz OR 2 GHz + 5/6 GHz)
+ * @psoc: psoc ctx
+ * @vdev: Pointer to vdev object
+ *
+ * Return: Success if MCC link is disabled else failure
+ */
+static QDF_STATUS
+policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
+			     struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t num_ml_sta = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	QDF_STATUS status;
+
+	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE))
+		return QDF_STATUS_E_FAILURE;
+
+	status = policy_mgr_is_ml_links_in_mcc_allowed(psoc, vdev,
+						       ml_sta_vdev_lst,
+						       &num_ml_sta);
+	if (QDF_IS_STATUS_ERROR(status))
+		return QDF_STATUS_E_FAILURE;
+
 	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
 				    MLO_LINK_FORCE_MODE_ACTIVE_NUM,
 				    num_ml_sta, ml_sta_vdev_lst);
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 9 - 5
components/tdls/core/src/wlan_tdls_ct.c

@@ -474,8 +474,8 @@ void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
 	return;
 }
 
-void tdls_implicit_send_discovery_request(
-				struct tdls_vdev_priv_obj *tdls_vdev_obj)
+void
+tdls_implicit_send_discovery_request(struct tdls_vdev_priv_obj *tdls_vdev_obj)
 {
 	struct tdls_peer *curr_peer;
 	struct tdls_peer *temp_peer;
@@ -574,12 +574,16 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev,
 			qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer);
 	}
 
-	tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDR_FMT
-		   " link_status %d", tdls_vdev->discovery_sent_cnt,
+	tdls_debug("[TDLS] vdev:%d action:%d (%s) sent_count:%u from peer " QDF_MAC_ADDR_FMT
+		   " link_status %d", wlan_vdev_get_id(tdls_vdev->vdev),
+		   TDLS_DISCOVERY_RESPONSE,
+		   "TDLS_DISCOVERY_RESPONSE",
+		   tdls_vdev->discovery_sent_cnt,
 		   QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes),
 		   curr_peer->link_status);
 
-	/* Since peer link status bases on vdev and stream goes through
+	/*
+	 * Since peer link status bases on vdev and stream goes through
 	 * vdev0 (assoc link) at start, rx/tx pkt count on vdev0, but
 	 * it choices vdev1 as tdls link, the peer status does not change on
 	 * vdev1 though it has been changed for vdev0 per the rx/tx pkt count.

+ 1 - 2
components/tdls/core/src/wlan_tdls_main.c

@@ -709,8 +709,7 @@ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg)
 	}
 	event = &notify->event;
 
-	tdls_debug("evt type: %s(%d)",
-		   tdls_get_event_type_str(event->message_type),
+	tdls_debug(" %s(%d)", tdls_get_event_type_str(event->message_type),
 		   event->message_type);
 
 	switch (event->message_type) {

+ 15 - 2
components/tdls/core/src/wlan_tdls_mgmt.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-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
@@ -896,6 +896,8 @@ QDF_STATUS tdls_set_link_mode(struct tdls_action_frame_request *req)
 	bool is_mlo_vdev;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct ml_nlink_change_event data;
+	uint8_t num_ml_sta = 0;
+	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
 
 	is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(req->vdev);
 	if (!is_mlo_vdev)
@@ -907,12 +909,22 @@ QDF_STATUS tdls_set_link_mode(struct tdls_action_frame_request *req)
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
+
 	if (req->tdls_mgmt.frame_type == TDLS_DISCOVERY_RESPONSE ||
 	    req->tdls_mgmt.frame_type == TDLS_DISCOVERY_REQUEST) {
 		mlo_tdls_vdev = wlan_mlo_get_tdls_link_vdev(req->vdev);
 		if (mlo_tdls_vdev)
 			return status;
 
+		status = policy_mgr_is_ml_links_in_mcc_allowed(
+						psoc, req->vdev,
+						ml_sta_vdev_lst,
+						&num_ml_sta);
+		if (QDF_IS_STATUS_SUCCESS(status)) {
+			tdls_err("ML STA Links in MCC, so don't send the TDLS frames");
+			return QDF_STATUS_E_FAILURE;
+		}
+
 		qdf_mem_zero(&data, sizeof(data));
 		data.evt.tdls.link_bitmap =
 				1 << wlan_vdev_get_link_id(req->vdev);
@@ -971,7 +983,8 @@ QDF_STATUS tdls_process_mgmt_req(
 
 	status = tdls_set_link_mode(tdls_mgmt_req);
 	if (status != QDF_STATUS_SUCCESS) {
-		tdls_err("failed to set link active");
+		tdls_err("failed to set link:%d active",
+			 wlan_vdev_get_link_id(tdls_mgmt_req->vdev));
 		status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
 							 status);
 		goto error_mgmt;

+ 35 - 35
core/mac/src/pe/lim/lim_process_tdls.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-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
@@ -552,6 +552,7 @@ static uint32_t lim_prepare_tdls_frame_header(struct mac_context *mac, uint8_t *
 	/* add payload type as TDLS */
 	*(pFrame + header_offset) = PAYLOAD_TYPE_TDLS;
 	header_offset += PAYLOAD_TYPE_TDLS_SIZE;
+
 	return header_offset;
 }
 
@@ -572,10 +573,8 @@ static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context, qdf_nbuf_t buf,
 	struct mac_context *mac_ctx = (struct mac_context *)context;
 	struct tdls_ethernet_hdr *ethernet_hdr;
 	tpSirMacActionFrameHdr action_hdr;
-	bool is_tdls_discvory_frm;
+	bool is_tdls_discvory_frm = false;
 
-	pe_debug("tdls_frm_session_id: %x tx_complete: %x",
-		 mac_ctx->lim.tdls_frm_session_id, tx_complete);
 
 	if (NO_SESSION != mac_ctx->lim.tdls_frm_session_id) {
 		if (buf &&
@@ -591,8 +590,6 @@ static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context, qdf_nbuf_t buf,
 				eth_890d_tdls_discvory_frm_hdr,
 				sizeof(eth_890d_tdls_discvory_frm_hdr));
 
-			pe_debug("is_tdls_discvory_frm: %d",
-				 is_tdls_discvory_frm);
 			if (is_tdls_discvory_frm &&
 			    tx_complete == WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK)
 				wlan_tdls_increment_discovery_attempts(
@@ -607,6 +604,10 @@ static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context, qdf_nbuf_t buf,
 		mac_ctx->lim.tdls_frm_session_id = NO_SESSION;
 	}
 
+	pe_debug("tdls_frm_session_id: %x tx_complete: %x is_discovery:%d",
+		 mac_ctx->lim.tdls_frm_session_id, tx_complete,
+		 is_tdls_discvory_frm);
+
 	if (buf)
 		qdf_nbuf_free(buf);
 
@@ -2393,15 +2394,20 @@ QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac,
 					&pe_session->dph.dphHashTable);
 	if (sta_ds)
 		qos_mode = sta_ds->qosMode;
-	tdls_link_type = (reason == REASON_TDLS_PEER_UNREACHABLE)
-				? TDLS_LINK_AP : TDLS_LINK_DIRECT;
-	nbytes = payload + (((IS_QOS_ENABLED(pe_session) &&
-			     (tdls_link_type == TDLS_LINK_AP)) ||
-			     ((tdls_link_type == TDLS_LINK_DIRECT) && qos_mode))
-			     ? sizeof(tSirMacDataHdr3a) :
-			     sizeof(tSirMacMgmtHdr))
-		 + sizeof(eth_890d_header)
-		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+	if (reason == REASON_TDLS_PEER_UNREACHABLE)
+		tdls_link_type = TDLS_LINK_AP;
+	else
+		tdls_link_type = TDLS_LINK_DIRECT;
+
+	nbytes = payload + sizeof(eth_890d_header) + PAYLOAD_TYPE_TDLS_SIZE;
+	nbytes += addIeLen;
+
+	if ((IS_QOS_ENABLED(pe_session) && tdls_link_type == TDLS_LINK_AP) ||
+	    (tdls_link_type == TDLS_LINK_DIRECT && qos_mode))
+		nbytes += sizeof(tSirMacDataHdr3a);
+	else
+		nbytes += sizeof(tSirMacMgmtHdr);
 
 #ifndef NO_PAD_TDLS_MIN_8023_SIZE
 	/* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
@@ -2493,12 +2499,11 @@ QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac,
 				    padlen - MIN_VENDOR_SPECIFIC_IE_SIZE);
 	}
 #endif
-	pe_debug("[TDLS] action: %d (%s) -%s-> OTA peer="QDF_MAC_ADDR_FMT,
-		TDLS_TEARDOWN,
-		lim_trace_tdls_action_string(TDLS_TEARDOWN),
-		((reason == REASON_TDLS_PEER_UNREACHABLE) ? "AP" :
-		    "DIRECT"),
-		QDF_MAC_ADDR_REF(peer_mac.bytes));
+	pe_debug("[TDLS] vdev:%d action: %d (%s) -%s-> OTA peer="QDF_MAC_ADDR_FMT,
+		 pe_session->vdev_id, TDLS_TEARDOWN,
+		 lim_trace_tdls_action_string(TDLS_TEARDOWN),
+		 ((reason == REASON_TDLS_PEER_UNREACHABLE) ? "AP" : "DIRECT"),
+		 QDF_MAC_ADDR_REF(peer_mac.bytes));
 
 	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
 
@@ -2510,9 +2515,7 @@ QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac,
 
 	qdf_status = wma_tx_frame_with_tx_complete_send(mac, packet,
 					(uint16_t)nbytes,
-					TID_AC_VI,
-					frame,
-					vdev_id,
+					TID_AC_VI, frame, vdev_id,
 					(reason == REASON_TDLS_PEER_UNREACHABLE)
 					? true : false);
 
@@ -2535,8 +2538,7 @@ lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
 			      uint8_t dialog,
 			      struct pe_session *pe_session,
 			      etdlsLinkSetupStatus setupStatus,
-			      uint8_t *addIe,
-			      uint16_t addIeLen,
+			      uint8_t *addIe, uint16_t addIeLen,
 			      enum wifi_traffic_ac ac)
 {
 	tDot11fTDLSSetupRsp *setup_rsp;
@@ -2758,10 +2760,9 @@ lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
 			pe_session);
 
 	pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x",
-		setup_rsp->VHTCaps.supportedChannelWidthSet,
-		setup_rsp->VHTCaps.rxMCSMap,
-		setup_rsp->VHTCaps.txMCSMap,
-		setup_rsp->VHTCaps.txSupDataRate);
+		 setup_rsp->VHTCaps.supportedChannelWidthSet,
+		 setup_rsp->VHTCaps.rxMCSMap, setup_rsp->VHTCaps.txMCSMap,
+		 setup_rsp->VHTCaps.txSupDataRate);
 	status = dot11f_pack_tdls_setup_rsp(mac, setup_rsp,
 					    pFrame + header_offset,
 					    nPayload, &nPayload);
@@ -2803,7 +2804,6 @@ lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
 		qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len,
 						      pFrame + header_offset +
 						      nPayload);
-
 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
 			pe_debug("assemble ml ie error");
 			mlo_ie_len = 0;
@@ -2812,10 +2812,10 @@ lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
 		nPayload += mlo_ie_len;
 	}
 
-	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT,
-		TDLS_SETUP_RESPONSE,
-		lim_trace_tdls_action_string(TDLS_SETUP_RESPONSE),
-		QDF_MAC_ADDR_REF(peer_mac.bytes));
+	pe_debug("[TDLS] vdev:%d action: %d (%s) -AP-> OTA peer="QDF_MAC_ADDR_FMT,
+		 pe_session->vdev_id, TDLS_SETUP_RESPONSE,
+		 lim_trace_tdls_action_string(TDLS_SETUP_RESPONSE),
+		 QDF_MAC_ADDR_REF(peer_mac.bytes));
 
 	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
 	vdev_id = lim_get_assoc_link_vdev_id(pe_session);