소스 검색

qcacld-3.0: Parse T2LM IE in Association Response

Add support to parse t2lm ie from association response frame
and store in mlo dev context. Once all links are up
the t2lm configuration will be applied.

CRs-Fixed: 3449605
Change-Id: Icd1f3c9bbdfbe1c2a8bfe119d92d6e686e21a7fd
Amruta Kulkarni 1 년 전
부모
커밋
0e0878c654

+ 8 - 3
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -1548,14 +1548,19 @@ cm_update_tid_mapping(struct wlan_objmgr_vdev *vdev)
 	if (!vdev || !vdev->mlo_dev_ctx)
 		return QDF_STATUS_E_NULL_VALUE;
 
-	if (!mlo_check_if_all_links_up(vdev))
+	if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev) ||
+	    !mlo_check_if_all_links_up(vdev))
 		return QDF_STATUS_E_FAILURE;
 
-	t2lm_ctx = &vdev->mlo_dev_ctx->t2lm_ctx;
+	t2lm_ctx = &vdev->mlo_dev_ctx->sta_ctx->copied_t2lm_ie_assoc_rsp;
+	if (!t2lm_ctx) {
+		mlme_err("T2LM ctx is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
 	status = wlan_process_bcn_prbrsp_t2lm_ie(vdev, t2lm_ctx, t2lm_ctx->tsf);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		mlme_err("T2LM IE beacon process failed");
-		return status;
 	}
 
 	return status;

+ 1 - 0
core/mac/src/include/parser_api.h

@@ -512,6 +512,7 @@ typedef struct sSirAssocRsp {
 #endif
 #ifdef WLAN_FEATURE_11BE_MLO
 	struct sir_multi_link_ie mlo_ie;
+	struct wlan_t2lm_context t2lm_ctx;
 #endif
 } tSirAssocRsp, *tpSirAssocRsp;
 

+ 64 - 0
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -932,6 +932,68 @@ lim_update_vdev_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static void
+lim_process_assoc_rsp_t2lm(struct pe_session *session,
+			   tpSirAssocRsp assoc_rsp)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_t2lm_context *t2lm_ctx;
+	struct wlan_mlo_dev_context *mlo_dev_ctx;
+
+	if (!session || !assoc_rsp) {
+		pe_err("invalid input parameters");
+		return;
+	}
+
+	vdev = session->vdev;
+	if (!vdev || !wlan_vdev_mlme_is_mlo_vdev(vdev))
+		return;
+
+	mlo_dev_ctx = wlan_vdev_get_mlo_dev_ctx(vdev);
+	if (!mlo_dev_ctx) {
+		pe_err("ml dev ctx is null");
+		return;
+	}
+
+	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
+		return;
+
+	if (assoc_rsp->t2lm_ctx.upcoming_t2lm.t2lm.direction ==
+	    WLAN_T2LM_INVALID_DIRECTION &&
+	    assoc_rsp->t2lm_ctx.established_t2lm.t2lm.direction ==
+	    WLAN_T2LM_INVALID_DIRECTION) {
+		pe_debug("No t2lm IE");
+		return;
+	}
+
+	t2lm_ctx = &mlo_dev_ctx->sta_ctx->copied_t2lm_ie_assoc_rsp;
+
+	if (assoc_rsp->t2lm_ctx.established_t2lm.t2lm.expected_duration_present &&
+	    !assoc_rsp->t2lm_ctx.established_t2lm.t2lm.mapping_switch_time_present &&
+	    assoc_rsp->t2lm_ctx.established_t2lm.t2lm.direction !=
+			WLAN_T2LM_INVALID_DIRECTION) {
+		qdf_mem_copy(&t2lm_ctx->established_t2lm.t2lm,
+			     &assoc_rsp->t2lm_ctx.established_t2lm.t2lm,
+			     sizeof(struct wlan_t2lm_info));
+	}
+
+	if (assoc_rsp->t2lm_ctx.upcoming_t2lm.t2lm.mapping_switch_time_present &&
+	    assoc_rsp->t2lm_ctx.established_t2lm.t2lm.direction !=
+			WLAN_T2LM_INVALID_DIRECTION) {
+		qdf_mem_copy(&t2lm_ctx->upcoming_t2lm.t2lm,
+			     &assoc_rsp->t2lm_ctx.upcoming_t2lm.t2lm,
+			     sizeof(struct wlan_t2lm_info));
+	}
+}
+#else
+static inline void
+lim_process_assoc_rsp_t2lm(struct pe_session *session,
+			   tpSirAssocRsp assoc_rsp)
+{
+}
+#endif
+
 /**
  * lim_process_assoc_rsp_frame() - Processes assoc response
  * @mac_ctx: Pointer to Global MAC structure
@@ -1482,6 +1544,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 
 	lim_objmgr_update_emlsr_caps(mac_ctx->psoc, session_entry->smeSessionId,
 				     assoc_rsp);
+
+	lim_process_assoc_rsp_t2lm(session_entry, assoc_rsp);
 	/*
 	 * Extract the AP capabilities from the beacon that
 	 * was received earlier

+ 75 - 0
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -3841,6 +3841,68 @@ sir_convert_assoc_resp_frame2_mlo_struct(struct mac_context *mac,
 	}
 	return status;
 }
+
+static QDF_STATUS
+sir_convert_assoc_resp_frame2_t2lm_struct(struct mac_context *mac,
+					  uint8_t *frame,
+					  uint32_t frame_len,
+					  struct pe_session *session_entry,
+					  tDot11fAssocResponse *ar,
+					  tpSirAssocRsp p_assoc_rsp)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_t2lm_context *t2lm_ctx;
+	/* add 3 bytes for extn_ie_header */
+	uint8_t ie[DOT11F_IE_T2LM_IE_MAX_LEN + 3];
+	struct wlan_t2lm_info t2lm;
+	uint8_t i;
+
+	t2lm_ctx = &p_assoc_rsp->t2lm_ctx;
+	qdf_mem_zero(&t2lm_ctx->established_t2lm.t2lm,
+		     sizeof(struct wlan_t2lm_info));
+	t2lm_ctx->established_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
+
+	qdf_mem_zero(&t2lm_ctx->upcoming_t2lm.t2lm,
+		     sizeof(struct wlan_t2lm_info));
+	t2lm_ctx->upcoming_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
+
+	if (!ar->num_t2lm_ie) {
+		pe_debug("T2LM IEs not present");
+		return status;
+	}
+
+	pe_debug("Number of T2LM IEs in assoc resp %d", ar->num_t2lm_ie);
+	for (i = 0; i < ar->num_t2lm_ie; i++) {
+		qdf_mem_zero(&ie[0], DOT11F_IE_T2LM_IE_MAX_LEN + 3);
+		qdf_mem_zero(&t2lm, sizeof(struct wlan_t2lm_info));
+		ie[ID_POS] = WLAN_ELEMID_EXTN_ELEM;
+		ie[TAG_LEN_POS] = ar->t2lm_ie[i].num_data + 1;
+		ie[IDEXT_POS] = WLAN_EXTN_ELEMID_T2LM;
+		qdf_mem_copy(&ie[3], &ar->t2lm_ie[i].data[0],
+			     ar->t2lm_ie[i].num_data + 3);
+		qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
+				   &ie[0], ar->t2lm_ie[i].num_data + 3);
+		status = wlan_mlo_parse_t2lm_info(&ie[0], &t2lm);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_debug("Parse T2LM IE fail");
+			return status;
+		}
+
+		if (!t2lm.mapping_switch_time_present &&
+		    t2lm.expected_duration_present) {
+			qdf_mem_copy(&t2lm_ctx->established_t2lm.t2lm, &t2lm,
+				     sizeof(struct wlan_t2lm_info));
+			pe_debug("Parse established T2LM IE success");
+		} else if (t2lm.mapping_switch_time_present) {
+			qdf_mem_copy(&t2lm_ctx->upcoming_t2lm.t2lm, &t2lm,
+				     sizeof(struct wlan_t2lm_info));
+			pe_debug("Parse upcoming T2LM IE success");
+		}
+		pe_debug("Parse T2LM IE success");
+	}
+	return status;
+}
+
 #else
 static inline QDF_STATUS
 sir_convert_assoc_resp_frame2_mlo_struct(struct mac_context *mac,
@@ -3852,6 +3914,17 @@ sir_convert_assoc_resp_frame2_mlo_struct(struct mac_context *mac,
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+static inline QDF_STATUS
+sir_convert_assoc_resp_frame2_t2lm_struct(struct mac_context *mac,
+					  uint8_t *frame,
+					  uint32_t frame_len,
+					  struct pe_session *session_entry,
+					  tDot11fAssocResponse *ar,
+					  tpSirAssocRsp p_assoc_rsp)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 #ifdef WLAN_FEATURE_SR
 static void sir_convert_assoc_resp_frame2_sr(tpSirAssocRsp pAssocRsp,
@@ -4155,6 +4228,8 @@ sir_convert_assoc_resp_frame2_struct(struct mac_context *mac,
 	fils_convert_assoc_rsp_frame2_struct(ar, pAssocRsp);
 	sir_convert_assoc_resp_frame2_mlo_struct(mac, frame, frame_len,
 						 session_entry, ar, pAssocRsp);
+	sir_convert_assoc_resp_frame2_t2lm_struct(mac, frame, frame_len,
+						  session_entry, ar, pAssocRsp);
 	pe_debug("ht %d vht %d vendor vht: cap %d op %d, he %d he 6ghband %d eht %d eht320 %d, max idle: present %d val %d, he mu edca %d wmm %d qos %d",
 		 ar->HTCaps.present, ar->VHTCaps.present,
 		 ar->vendor_vht_ie.VHTCaps.present,