Browse Source

qcacmn: Add support to extract link removal TLVs from MGMT Rx event

To assist the Host in ML reconfiguration element construction for probe
responses, FW sends MLO link removal information as part of the MGMT Rx
event containing the corresponding probe request. This information is an
array of TLVs, one TLV for each link that is undergoing link removal from
the MLD for which this probe request is intended. The TLV carries the link
removal TBTT countdown value maintained by the FW for that link.
Add support to extract the same.

CRs-Fixed: 3335361
Change-Id: I16c6791a443ddb166da596d404a52ff2a38da291
Shiva Krishna Pittala 2 years ago
parent
commit
11fa724d8a

+ 0 - 2
target_if/core/src/target_if_main.c

@@ -111,9 +111,7 @@
 #include "wmi_unified_api.h"
 #include <target_if_twt.h>
 
-#ifdef WLAN_FEATURE_11BE_MLO
 #include <target_if_mlo_mgr.h>
-#endif
 
 #ifdef WLAN_FEATURE_COAP
 #include <target_if_coap.h>

+ 27 - 3
target_if/mlo_mgr/inc/target_if_mlo_mgr.h

@@ -27,9 +27,10 @@
 #include <target_if.h>
 #include <wlan_lmac_if_def.h>
 
+#ifdef WLAN_FEATURE_11BE_MLO
 /**
  * target_if_mlo_get_rx_ops() - get rx ops
- * @tx_ops: pointer to target_if tx ops
+ * @psoc: pointer to soc object
  *
  * API to retrieve the MLO rx ops from the psoc context
  *
@@ -51,7 +52,7 @@ target_if_mlo_get_rx_ops(struct wlan_objmgr_psoc *psoc)
 
 /**
  * target_if_mlo_get_tx_ops() - get tx ops
- * @tx_ops: pointer to target_if tx ops
+ * @psoc: pointer to soc object
  *
  * API to retrieve the MLO tx ops from the psoc context
  *
@@ -92,5 +93,28 @@ QDF_STATUS target_if_mlo_send_link_removal_cmd(
 		struct wlan_objmgr_psoc *psoc,
 		const struct mlo_link_removal_cmd_params *param);
 
+/**
+ * target_if_extract_mlo_link_removal_info_mgmt_rx() - Extract MLO link removal
+ * information from MGMT Rx event
+ * @wmi_handle: WMI handle
+ * @evt_buf: Event buffer
+ * @rx_event: MGMT Rx event parameters
+ *
+ * Return: QDF_STATUS of operation
+ */
+QDF_STATUS
+target_if_extract_mlo_link_removal_info_mgmt_rx(
+		wmi_unified_t wmi_handle,
+		void *evt_buf,
+		struct mgmt_rx_event_params *rx_event);
+#else
+static inline QDF_STATUS
+target_if_extract_mlo_link_removal_info_mgmt_rx(
+		wmi_unified_t wmi_handle,
+		void *evt_buf,
+		struct mgmt_rx_event_params *rx_event)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #endif /* __TARGET_IF_MLO_MGR_H__ */
-

+ 49 - 0
target_if/mlo_mgr/src/target_if_mlo_mgr.c

@@ -142,6 +142,55 @@ exit:
 	return qdf_status_to_os_return(status);
 }
 
+QDF_STATUS
+target_if_extract_mlo_link_removal_info_mgmt_rx(
+		wmi_unified_t wmi_handle,
+		void *evt_buf,
+		struct mgmt_rx_event_params *rx_event)
+{
+	QDF_STATUS status;
+	struct mgmt_rx_mlo_link_removal_info *link_removal_info;
+
+	if (!rx_event) {
+		target_if_err("Invalid rx_event");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	rx_event->link_removal_info = NULL;
+	if (!rx_event->num_link_removal_info) {
+		/**
+		 * This is not an error. Only probe request frames will contain
+		 * Link removal TLVs, that too only till the link removal TBTT
+		 * countdown completion.
+		 */
+		target_if_debug("Link removal TLVs are not present");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	link_removal_info = qdf_mem_malloc(rx_event->num_link_removal_info *
+					   sizeof(*link_removal_info));
+	if (!link_removal_info) {
+		target_if_err("Couldn't allocate memory for link_removal_info");
+		rx_event->num_link_removal_info = 0;
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wmi_extract_mgmt_rx_mlo_link_removal_info(
+					wmi_handle, evt_buf,
+					link_removal_info,
+					rx_event->num_link_removal_info);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("Unable to extract link removal TLVs");
+		rx_event->num_link_removal_info = 0;
+		qdf_mem_free(link_removal_info);
+		return status;
+	}
+
+	rx_event->link_removal_info = link_removal_info;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * target_if_mlo_register_event_handler() - function to register handler for
  *  mlo related wmi event from firmware.

+ 15 - 1
umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h

@@ -884,6 +884,8 @@ struct mlo_mgmt_ml_info {
  * @pn_params: Frame PN params
  * @ext_params: Extended params
  * @frm_con_ap: Frame is from connected ap
+ * @link_removal_info: MLO link removal information array
+ * @num_link_removal_info: Number of elements in @link_removal_info
  */
 struct mgmt_rx_event_params {
 	uint32_t    chan_freq;
@@ -908,9 +910,18 @@ struct mgmt_rx_event_params {
 	struct frm_conn_ap is_conn_ap;
 #ifdef WLAN_FEATURE_11BE_MLO
 	struct mlo_mgmt_ml_info cu_params;
+	struct mgmt_rx_mlo_link_removal_info *link_removal_info;
+	int num_link_removal_info;
 #endif
 };
 
+#ifdef WLAN_FEATURE_11BE_MLO
+#define free_mgmt_rx_mlo_link_removal_info(rx_params) \
+			qdf_mem_free((rx_params)->link_removal_info)
+#else
+#define free_mgmt_rx_mlo_link_removal_info(rx_params)
+#endif
+
 #ifdef WLAN_MGMT_RX_REO_SUPPORT
 static inline
 struct mgmt_rx_event_params *alloc_mgmt_rx_event_params(void)
@@ -947,6 +958,7 @@ free_mgmt_rx_event_params(struct mgmt_rx_event_params *rx_params)
 	if (rx_params) {
 		qdf_mem_free(rx_params->ext_params);
 		qdf_mem_free(rx_params->reo_params);
+		free_mgmt_rx_mlo_link_removal_info(rx_params);
 	}
 
 	qdf_mem_free(rx_params);
@@ -975,8 +987,10 @@ struct mgmt_rx_event_params *alloc_mgmt_rx_event_params(void)
 static inline void
 free_mgmt_rx_event_params(struct mgmt_rx_event_params *rx_params)
 {
-	if (rx_params)
+	if (rx_params) {
 		qdf_mem_free(rx_params->ext_params);
+		free_mgmt_rx_mlo_link_removal_info(rx_params);
+	}
 
 	qdf_mem_free(rx_params);
 }

+ 13 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h

@@ -1042,4 +1042,17 @@ struct mlo_link_removal_evt_params {
 	uint8_t vdev_id;
 	struct mlo_link_removal_tbtt_info tbtt_info;
 };
+
+/*
+ * struct mgmt_rx_mlo_link_removal_info - Information, sent in MGMT Rx event, of
+ * a link undergoing removal from its MLD
+ * @vdev_id: Vdev ID of the link undergoing removal
+ * @hw_link_id: HW link ID of the link undergoing removal
+ * @tbtt_count: Delete timer TBTT count of the link undergoing removal
+ */
+struct mgmt_rx_mlo_link_removal_info {
+	uint8_t vdev_id;
+	uint8_t hw_link_id;
+	uint16_t tbtt_count;
+};
 #endif

+ 16 - 0
wmi/inc/wmi_unified_11be_api.h

@@ -103,6 +103,22 @@ QDF_STATUS wmi_extract_mlo_link_removal_tbtt_update(
 		struct wmi_unified *wmi_handle,
 		void *buf,
 		struct mlo_link_removal_tbtt_info *tbtt_info);
+
+/**
+ * wmi_extract_mgmt_rx_mlo_link_removal_info() - Extract MLO link removal info
+ * from MGMT Rx event
+ * @wmi: wmi handle
+ * @buf: event buffer
+ * @link_removal_info: link removal information array to be populated
+ * @num_link_removal_info: Number of elements in @link_removal_info
+ *
+ * Return: QDF_STATUS of operation
+ */
+QDF_STATUS wmi_extract_mgmt_rx_mlo_link_removal_info(
+		struct wmi_unified *wmi,
+		void *buf,
+		struct mgmt_rx_mlo_link_removal_info *link_removal_info,
+		int num_link_removal_info);
 #endif /*WLAN_FEATURE_11BE_MLO*/
 
 #ifdef WLAN_FEATURE_11BE

+ 23 - 0
wmi/inc/wmi_unified_11be_tlv.h

@@ -194,6 +194,22 @@ uint8_t *peer_delete_add_mlo_params(uint8_t *buf_ptr,
  *  @wmi_handle: WMI handle
  */
 void wmi_11be_attach_tlv(wmi_unified_t wmi_handle);
+
+/**
+ * extract_mgmt_rx_mlo_link_removal_tlv_count() - Extract the number of link
+ * removal TLVs from MGMT Rx event
+ * @num_link_removal_tlvs: Number of link removal TLVs
+ * @hdr: MGMT Rx event parameters to be populated
+ *
+ * Return: None
+ */
+static inline void
+extract_mgmt_rx_mlo_link_removal_tlv_count(
+	int num_link_removal_tlvs,
+	struct mgmt_rx_event_params *hdr)
+{
+	hdr->num_link_removal_info = num_link_removal_tlvs;
+}
 #else
 static uint8_t *vdev_create_add_mlo_params(uint8_t *buf_ptr,
 					   struct vdev_create_params *param)
@@ -323,5 +339,12 @@ static uint8_t *peer_delete_add_mlo_params(uint8_t *buf_ptr,
 
 static void wmi_11be_attach_tlv(wmi_unified_t wmi_handle)
 { }
+
+static inline void
+extract_mgmt_rx_mlo_link_removal_tlv_count(
+	int num_link_removal_tlvs,
+	struct mgmt_rx_event_params *hdr)
+{
+}
 #endif /*WLAN_FEATURE_11BE_MLO*/
 #endif /*_WMI_UNIFIED_11BE_TLV_H_*/

+ 6 - 0
wmi/inc/wmi_unified_priv.h

@@ -3049,6 +3049,12 @@ QDF_STATUS (*extract_mlo_link_removal_tbtt_update)(
 		struct wmi_unified *wmi_handle,
 		void *buf,
 		struct mlo_link_removal_tbtt_info *tbtt_info);
+
+QDF_STATUS (*extract_mgmt_rx_mlo_link_removal_info)(
+		struct wmi_unified *wmi_handle,
+		void *buf,
+		struct mgmt_rx_mlo_link_removal_info *link_removal_info,
+		int num_link_removal_info);
 #endif
 
 #ifdef WLAN_FEATURE_SON

+ 15 - 0
wmi/src/wmi_unified_11be_api.c

@@ -153,3 +153,18 @@ QDF_STATUS wmi_extract_mlo_link_removal_tbtt_update(
 
 	return QDF_STATUS_E_FAILURE;
 }
+
+QDF_STATUS wmi_extract_mgmt_rx_mlo_link_removal_info(
+		struct wmi_unified *wmi,
+		void *buf,
+		struct mgmt_rx_mlo_link_removal_info *link_removal_info,
+		int num_link_removal_info)
+{
+	if (wmi->ops->extract_mgmt_rx_mlo_link_removal_info)
+		return wmi->ops->extract_mgmt_rx_mlo_link_removal_info(
+							wmi, buf,
+							link_removal_info,
+							num_link_removal_info);
+
+	return QDF_STATUS_E_FAILURE;
+}

+ 57 - 0
wmi/src/wmi_unified_11be_tlv.c

@@ -740,6 +740,61 @@ extract_mlo_link_removal_tbtt_update_tlv(
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * extract_mgmt_rx_mlo_link_removal_info_tlv() - Extract MLO link removal info
+ * from MGMT Rx event
+ * @wmi_handle: wmi handle
+ * @buf: event buffer
+ * @link_removal_info: link removal information array to be populated
+ * @num_link_removal_info: Number of elements in @link_removal_info
+ *
+ * Return: QDF_STATUS of operation
+ */
+static QDF_STATUS
+extract_mgmt_rx_mlo_link_removal_info_tlv(
+	struct wmi_unified *wmi_handle,
+	void *buf,
+	struct mgmt_rx_mlo_link_removal_info *link_removal_info,
+	int num_link_removal_info)
+{
+	WMI_MGMT_RX_EVENTID_param_tlvs *param_buf = buf;
+	wmi_mlo_link_removal_tbtt_count *tlv_arr;
+	int tlv_idx = 0;
+	struct mgmt_rx_mlo_link_removal_info *info;
+
+	if (!param_buf) {
+		wmi_err_rl("Param_buf is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!link_removal_info) {
+		wmi_err_rl("Writable argument is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (num_link_removal_info != param_buf->num_link_removal_tbtt_count) {
+		wmi_err_rl("link_removal_info array size (%d) is not equal to"
+			   "number of corresponding TLVs(%d) present in event",
+			   num_link_removal_info,
+			   param_buf->num_link_removal_tbtt_count);
+		return QDF_STATUS_E_RANGE;
+	}
+
+	tlv_arr = param_buf->link_removal_tbtt_count;
+	for (; tlv_idx < param_buf->num_link_removal_tbtt_count; tlv_idx++) {
+		info = &link_removal_info[tlv_idx];
+
+		info->hw_link_id = WMI_MLO_LINK_REMOVAL_GET_LINKID(
+					tlv_arr[tlv_idx].tbtt_info);
+		info->vdev_id = WMI_MLO_LINK_REMOVAL_GET_VDEVID(
+					tlv_arr[tlv_idx].tbtt_info);
+		info->tbtt_count = WMI_MLO_LINK_REMOVAL_GET_TBTT_COUNT(
+					tlv_arr[tlv_idx].tbtt_info);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 #ifdef WLAN_FEATURE_11BE
 size_t peer_assoc_t2lm_params_size(struct peer_assoc_params *req)
 {
@@ -1459,4 +1514,6 @@ void wmi_11be_attach_tlv(wmi_unified_t wmi_handle)
 			extract_mlo_link_removal_evt_fixed_param_tlv;
 	ops->extract_mlo_link_removal_tbtt_update =
 			extract_mlo_link_removal_tbtt_update_tlv;
+	ops->extract_mgmt_rx_mlo_link_removal_info =
+			extract_mgmt_rx_mlo_link_removal_info_tlv;
 }

+ 3 - 0
wmi/src/wmi_unified_tlv.c

@@ -12757,6 +12757,9 @@ static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle,
 
 	*bufp = param_tlvs->bufp;
 
+	extract_mgmt_rx_mlo_link_removal_tlv_count(
+		param_tlvs->num_link_removal_tbtt_count, hdr);
+
 	return QDF_STATUS_SUCCESS;
 }