Browse Source

qcacld-3.0: Validate T2LM IE

Adds support to parse and validate T2LM IE,
based on tid to link mapping pick the
association link for MLO connection.

Change-Id: I8ea23ff10f2a637148686f1e2194fd8cc1f4fb90
CRs-Fixed: 3344675
Amruta Kulkarni 2 years ago
parent
commit
63583f71ac

+ 32 - 9
components/umac/mlme/mlo_mgr/inc/wlan_t2lm_api.h

@@ -26,7 +26,6 @@
 #include "parser_api.h"
 #include "lim_send_messages.h"
 
-#ifdef WLAN_FEATURE_11BE
 /**
  * struct t2lm_event_data - TID to Link mapping event data
  * @status: qdf status used to indicate if t2lm action frame status
@@ -45,6 +44,7 @@ struct t2lm_event_data {
  * @WLAN_T2LM_EV_ACTION_FRAME_RX_RESP:Handle T2LM response frame received from AP
  * @WLAN_T2LM_EV_ACTION_FRAME_RX_TEARDOWN:Handle received teardown frame event
  * @WLAN_T2LM_EV_ACTION_FRAME_TX_TEARDOWN:Handle sending teardown frame event
+ * @WLAN_T2LM_EV_ACTION_FRAME_MAX: Maximum T2LM action frame event value
  */
 enum wlan_t2lm_evt {
 	WLAN_T2LM_EV_ACTION_FRAME_RX_REQ = 0,
@@ -56,6 +56,7 @@ enum wlan_t2lm_evt {
 	WLAN_T2LM_EV_ACTION_FRAME_MAX = 6,
 };
 
+#ifdef WLAN_FEATURE_11BE_MLO
 /**
  * t2lm_deliver_event - Handler to deliver T2LM event
  * @vdev: vdev pointer
@@ -143,6 +144,21 @@ QDF_STATUS t2lm_handle_rx_teardown(struct wlan_objmgr_vdev *vdev,
 QDF_STATUS t2lm_handle_tx_teardown(struct wlan_objmgr_vdev *vdev,
 				   struct t2lm_event_data *event_data);
 
+/**
+ * wlan_t2lm_validate_candidate - Validate candidate based on T2LM IE
+ * @cm_ctx: connection manager context pointer
+ * @scan_entry: scan entry pointer
+ *
+ * This api will be called to validate candidate based on T2LM IE received
+ * in beacon or probe response
+ *
+ * Return: qdf_status
+ */
+
+QDF_STATUS
+wlan_t2lm_validate_candidate(struct cnx_mgr *cm_ctx,
+			     struct scan_cache_entry *scan_entry);
+
 #else
 static inline QDF_STATUS
 t2lm_deliver_event(struct wlan_objmgr_vdev *vdev,
@@ -167,29 +183,36 @@ t2lm_handle_tx_resp(struct wlan_objmgr_vdev *vdev,
 }
 
 static inline QDF_STATUS
-t2lm_handle_rx_req(struct wlan_objmgr_vdev *vdev,
-		   struct t2lm_mgr_event_data *event_data)
+t2lm_handle_tx_req(struct wlan_objmgr_vdev *vdev,
+		   struct t2lm_event_data *event_data)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
 
 static inline QDF_STATUS
-t2lm_handle_rx_req(struct wlan_objmgr_vdev *vdev,
-		   struct t2lm_event_data *event_data)
+t2lm_handle_rx_resp(struct wlan_objmgr_vdev *vdev,
+		    struct t2lm_event_data *event_data)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
 
 static inline QDF_STATUS
-t2lm_handle_rx_req(struct wlan_objmgr_vdev *vdev,
-		   struct t2lm_event_data *event_data)
+t2lm_handle_rx_teardown(struct wlan_objmgr_vdev *vdev,
+			struct t2lm_event_data *event_data)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
 
 static inline QDF_STATUS
-t2lm_handle_rx_req(struct wlan_objmgr_vdev *vdev,
-		   struct t2lm_event_data *event_data)
+t2lm_handle_tx_teardown(struct wlan_objmgr_vdev *vdev,
+			struct t2lm_event_data *event_data)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+wlan_t2lm_validate_candidate(struct cnx_mgr *cm_ctx,
+			     struct scan_cache_entry *scan_entry)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }

+ 112 - 0
components/umac/mlme/mlo_mgr/src/wlan_t2lm_api.c

@@ -20,6 +20,7 @@
 #include <wlan_cmn.h>
 #include <wlan_cm_public_struct.h>
 #include "wlan_t2lm_api.h"
+#include <wlan_mlo_t2lm.h>
 
 static
 const char *t2lm_get_event_str(enum wlan_t2lm_evt event)
@@ -140,3 +141,114 @@ QDF_STATUS t2lm_deliver_event(struct wlan_objmgr_vdev *vdev,
 
 	return status;
 }
+
+static uint16_t
+t2lm_get_tids_mapped_link_id(uint16_t link_map_tid)
+{
+	uint16_t all_tids_mapped_link_id = 0;
+	uint8_t i;
+	uint8_t bit_mask = 1;
+
+	for (i = 0; i < WLAN_T2LM_MAX_NUM_LINKS; i++) {
+		if (link_map_tid & bit_mask)
+			all_tids_mapped_link_id = i;
+		bit_mask = bit_mask << 1;
+	}
+
+	return all_tids_mapped_link_id;
+}
+
+static QDF_STATUS
+t2lm_find_tid_mapped_link_id(struct wlan_t2lm_info *t2lm_info,
+			     uint16_t *tid_mapped_link_id)
+{
+	uint16_t link_map_tid;
+	uint8_t tid;
+
+	if (!t2lm_info)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	if (t2lm_info->default_link_mapping) {
+		t2lm_debug("T2LM ie has default link mapping");
+		*tid_mapped_link_id = 0xFFFF;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	link_map_tid = t2lm_info->ieee_link_map_tid[0];
+	for (tid = 1; tid < T2LM_MAX_NUM_TIDS; tid++) {
+		if (link_map_tid != t2lm_info->ieee_link_map_tid[tid]) {
+			mlme_debug("all tids are not mapped to same link set");
+			return QDF_STATUS_E_FAILURE;
+		}
+	}
+
+	*tid_mapped_link_id = t2lm_get_tids_mapped_link_id(link_map_tid);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_t2lm_validate_candidate(struct cnx_mgr *cm_ctx,
+			     struct scan_cache_entry *scan_entry)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_t2lm_context t2lm_ctx;
+	uint8_t tid_map_link_id = 0;
+	uint16_t tid_mapped_link_id[WLAN_MAX_T2LM_IE];
+	uint8_t i;
+
+	if (!scan_entry)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	if (!cm_ctx || !cm_ctx->vdev)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	vdev = cm_ctx->vdev;
+
+	if (scan_entry->ie_list.t2lm[0]) {
+		if (!vdev || !vdev->mlo_dev_ctx) {
+			status = QDF_STATUS_E_NULL_VALUE;
+			goto end;
+		}
+
+		t2lm_ctx = vdev->mlo_dev_ctx->t2lm_ctx;
+		status = wlan_mlo_parse_bcn_prbresp_t2lm_ie(&t2lm_ctx,
+							    scan_entry->ie_list.t2lm[0]);
+		if (QDF_IS_STATUS_ERROR(status))
+			goto end;
+
+		if (!t2lm_ctx.num_of_t2lm_ie) {
+			t2lm_debug("T2LM IE parsing failed");
+			status = QDF_STATUS_E_FAILURE;
+			goto end;
+		}
+
+		for (i = 0; i < t2lm_ctx.num_of_t2lm_ie; i++) {
+			status = t2lm_find_tid_mapped_link_id(&t2lm_ctx.t2lm_ie[i].t2lm,
+							      &tid_mapped_link_id[i]);
+			if (QDF_IS_STATUS_ERROR(status))
+				goto end;
+		}
+
+		if (t2lm_ctx.num_of_t2lm_ie == WLAN_MAX_T2LM_IE) {
+			tid_map_link_id = tid_mapped_link_id[0] & tid_mapped_link_id[1];
+			if (!tid_map_link_id)
+				tid_map_link_id = tid_mapped_link_id[0];
+		} else {
+			tid_map_link_id = tid_mapped_link_id[0];
+		}
+
+		if (tid_map_link_id == scan_entry->ml_info.self_link_id) {
+			t2lm_debug("self link id %d, tid map link id %d",
+				   scan_entry->ml_info.self_link_id,
+				   tid_map_link_id);
+			status = QDF_STATUS_SUCCESS;
+		}
+	} else {
+		t2lm_debug("T2LM IE is not present in scan entry");
+		status = QDF_STATUS_SUCCESS;
+	}
+
+end:
+	return status;
+}