Browse Source

qcacld-3.0: Fixing ML Partner Info Sequence Issue in Assoc Response Parsing

Currently, driver fills the session->ml_partner_info based
on the ML partner info present in the received assoc response
frame. However, it is possible that the AP may send a
different ML partner info sequence in the assoc resp frame,
leading to incorrect info send during PEER_ASSOC_CMDID.

For instance, when establishing a 3-link connection, the STA
selects 6 GHz as the assoc link and 5 GHz + 2.4 GHz as partner links.
The STA expects the same partner sequence (5 GHz and 2.4 GHz)
in the assoc resp frame. However, the AP can send a different
sequence (2.4 GHz + 5 GHz).

To fix this issue, modifies the parsing of the ML partner info duing
assoc response frame. Instead of relying on the ML partner info
from the assoc response frame, updates the session->ml_partner_info
based on the partner sequence present in the the mlo_mgr context.
This ensure that the ML partner info sequence is correct and matches
the expected sequence during the association.

Change-Id: I93236afae4c7915fb2c9bd6ad209feae1312126f
CRs-Fixed: 3530714
Deeksha Gupta 1 year ago
parent
commit
a2e4ae849a
1 changed files with 33 additions and 1 deletions
  1. 33 1
      core/mac/src/sys/legacy/src/utils/src/parser_api.c

+ 33 - 1
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -3755,6 +3755,34 @@ sir_convert_assoc_resp_frame2_eht_struct(tDot11fAssocResponse *ar,
 #endif
 
 #ifdef WLAN_FEATURE_11BE_MLO
+static QDF_STATUS
+sir_convert_assoc_resp_to_partner_mlo_struct(struct pe_session *session_entry,
+					     struct mlo_partner_info *partner_info,
+					     struct mlo_partner_info *ml_partner_info)
+{
+	uint16_t i, partner_idx = 0, j, link_id;
+	struct mlo_link_info *link_info;
+
+	link_info = mlo_mgr_get_ap_link(session_entry->vdev);
+	if (!link_info)
+		return QDF_STATUS_E_FAILURE;
+
+	for (i = 1; i < WLAN_MAX_ML_BSS_LINKS; i++) {
+		link_id = link_info[i].link_id;
+		for (j = 0; j < partner_info->num_partner_links; j++) {
+			if (partner_info->partner_link_info[j].link_id == link_id) {
+				ml_partner_info->partner_link_info[partner_idx++] =
+							partner_info->partner_link_info[j];
+				break;
+			}
+		}
+	}
+
+	ml_partner_info->num_partner_links = partner_idx;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 static QDF_STATUS
 sir_convert_assoc_resp_frame2_mlo_struct(struct mac_context *mac,
 					 uint8_t *frame,
@@ -3773,6 +3801,7 @@ sir_convert_assoc_resp_frame2_mlo_struct(struct mac_context *mac,
 	uint16_t msd_cap;
 	struct qdf_mac_addr mld_mac_addr;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct mlo_partner_info partner_info;
 
 	if (ar->mlo_ie.present) {
 		status = util_find_mlie(frame + WLAN_ASSOC_RSP_IES_OFFSET,
@@ -3782,7 +3811,10 @@ sir_convert_assoc_resp_frame2_mlo_struct(struct mac_context *mac,
 			ml_ie_info = &p_assoc_rsp->mlo_ie.mlo_ie;
 			util_get_bvmlie_persta_partner_info(ml_ie,
 					       ml_ie_total_len,
-					       &session_entry->ml_partner_info);
+					       &partner_info);
+			sir_convert_assoc_resp_to_partner_mlo_struct(session_entry,
+								     &partner_info,
+								     &session_entry->ml_partner_info);
 			if (!wlan_cm_is_roam_sync_in_progress(mac->psoc, session_entry->vdev_id)) {
 				session_entry->ml_partner_info.num_partner_links =
 				QDF_MIN(