Bläddra i källkod

qcacmn: Add HAL specific api to support tx monitor

Added HAL specific api to support tx monitor,
	1. to get buffer address
	2. get number of users
	3. get corresponding structure to handle tx monitor and
	4. parse limited TLV tag.

Change-Id: Ic354c76b3bcf5fa454db973c2aa4ee5f9c1b4208
nobelj 3 år sedan
förälder
incheckning
eb6d660139

+ 109 - 1
hal/wifi3.0/be/hal_be_api_mon.h

@@ -238,6 +238,48 @@ enum hal_tx_tlv_status {
 	HAL_MON_TX_STATUS_PPDU_NOT_DONE,
 };
 
+enum txmon_transmission_type {
+	TXMON_SU_TRANSMISSION = 0,
+	TXMON_MU_TRANSMISSION,
+	TXMON_MU_SU_TRANSMISSION,
+	TXMON_MU_MIMO_TRANSMISSION = 1,
+	TXMON_MU_OFDMA_TRANMISSION
+};
+
+#define TXMON_HAL(hal_tx_ppdu_info, field)		\
+			hal_tx_ppdu_info->field
+#define TXMON_HAL_STATUS(hal_tx_ppdu_info, field)	\
+			hal_tx_ppdu_info->rx_status.field
+#define TXMON_HAL_USER(hal_tx_ppdu_info, user_id, field)		\
+			hal_tx_ppdu_info->rx_user_status[user_id].field
+
+#define TXMON_STATUS_INFO(hal_tx_status_info, field)	\
+			hal_tx_status_info->field
+
+struct hal_tx_status_info {
+	uint8_t reception_type;
+	uint8_t transmission_type;
+	uint8_t medium_prot_type;
+
+	void *buffer;
+	uint32_t offset;
+	uint32_t len_bytes;
+};
+
+struct hal_tx_ppdu_info {
+	uint32_t ppdu_id;
+
+	uint32_t num_users	:8,
+		 is_used	:1,
+		 is_data	:1,
+		 reserved	:23;
+
+	uint32_t prot_tlv_status;
+
+	struct mon_rx_status rx_status;
+	struct mon_rx_user_status rx_user_status[];
+};
+
 /**
  * hal_tx_status_get_next_tlv() - get next tx status TLV
  * @tx_tlv: pointer to TLV header
@@ -255,7 +297,57 @@ hal_tx_status_get_next_tlv(uint8_t *tx_tlv) {
 					    HAL_RX_TLV32_HDR_SIZE + 3)) & (~3));
 }
 
-/*
+/**
+ * hal_txmon_status_parse_tlv() - process transmit info TLV
+ * @hal_soc: HAL soc handle
+ * @data_ppdu_info: pointer to hal data ppdu info
+ * @prot_ppdu_info: pointer to hal prot ppdu info
+ * @data_status_info: pointer to data status info
+ * @prot_status_info: pointer to prot status info
+ * @tx_tlv_hdr: pointer to TLV header
+ * @status_frag: pointer to status frag
+ *
+ * Return: HAL_TLV_STATUS_PPDU_NOT_DONE
+ */
+static inline uint32_t
+hal_txmon_status_parse_tlv(hal_soc_handle_t hal_soc_hdl,
+			   void *data_ppdu_info,
+			   void *prot_ppdu_info,
+			   void *data_status_info,
+			   void *prot_status_info,
+			   void *tx_tlv_hdr,
+			   qdf_frag_t status_frag)
+{
+	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
+
+	return hal_soc->ops->hal_txmon_status_parse_tlv(data_ppdu_info,
+							prot_ppdu_info,
+							data_status_info,
+							prot_status_info,
+							tx_tlv_hdr,
+							status_frag);
+}
+
+/**
+ * hal_txmon_status_get_num_users() - api to get num users from start of fes
+ * window
+ * @hal_soc: HAL soc handle
+ * @tx_tlv_hdr: pointer to TLV header
+ * @num_users: reference to number of user
+ *
+ * Return: status
+ */
+static inline uint32_t
+hal_txmon_status_get_num_users(hal_soc_handle_t hal_soc_hdl,
+			       void *tx_tlv_hdr, uint8_t *num_users)
+{
+	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
+
+	return hal_soc->ops->hal_txmon_status_get_num_users(tx_tlv_hdr,
+							    num_users);
+}
+
+/**
  * hal_txmon_status_free_buffer() - api to free status buffer
  * @hal_soc: HAL soc handle
  * @status_frag: qdf_frag_t buffer
@@ -271,5 +363,21 @@ hal_txmon_status_free_buffer(hal_soc_handle_t hal_soc_hdl,
 	if (hal_soc->ops->hal_txmon_status_free_buffer)
 		hal_soc->ops->hal_txmon_status_free_buffer(status_frag);
 }
+
+/**
+ * hal_tx_status_get_tlv_tag() - api to get tlv tag
+ * @tx_tlv_hdr: pointer to TLV header
+ *
+ * Return tlv_tag
+ */
+static inline uint32_t
+hal_tx_status_get_tlv_tag(void *tx_tlv_hdr)
+{
+	uint32_t tlv_tag = 0;
+
+	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(tx_tlv_hdr);
+
+	return tlv_tag;
+}
 #endif /* QCA_MONITOR_2_0_SUPPORT */
 #endif /* _HAL_BE_API_MON_H_ */

+ 228 - 0
hal/wifi3.0/be/hal_be_generic_api.h

@@ -2564,6 +2564,116 @@ hal_txmon_get_buffer_addr_generic_be(void *tx_tlv,
 	return buf_addr;
 }
 
+#if defined(TX_MONITOR_WORD_MASK)
+/**
+ * hal_txmon_get_num_users() - get num users from tx_fes_setup tlv
+ *
+ * @tx_tlv: pointer to tx_fes_setup tlv header
+ *
+ * Return: number of users
+ */
+static inline uint8_t
+hal_txmon_get_num_users(void *tx_tlv)
+{
+	hal_tx_fes_setup_t *tx_fes_setup = (hal_tx_fes_setup_t *)tx_tlv;
+
+	return tx_fes_setup->number_of_users;
+}
+
+/**
+ * hal_txmon_parse_tx_fes_setup() - parse tx_fes_setup tlv
+ *
+ * @tx_tlv: pointer to tx_fes_setup tlv header
+ * @ppdu_info: pointer to hal_tx_ppdu_info
+ *
+ * Return: void
+ */
+static inline void
+hal_txmon_parse_tx_fes_setup(void *tx_tlv,
+			     struct hal_tx_ppdu_info *tx_ppdu_info)
+{
+	hal_tx_fes_setup_t *tx_fes_setup = (hal_tx_fes_setup_t *)tx_tlv;
+
+	tx_ppdu_info->num_users = tx_fes_setup->number_of_users;
+}
+#else
+/**
+ * hal_txmon_get_num_users() - get num users from tx_fes_setup tlv
+ *
+ * @tx_tlv: pointer to tx_fes_setup tlv header
+ *
+ * Return: number of users
+ */
+static inline uint8_t
+hal_txmon_get_num_users(void *tx_tlv)
+{
+	uint8_t num_users = HAL_TX_DESC_GET(tx_tlv,
+					    TX_FES_SETUP, NUMBER_OF_USERS);
+
+	return num_users;
+}
+
+/**
+ * hal_txmon_parse_tx_fes_setup() - parse tx_fes_setup tlv
+ *
+ * @tx_tlv: pointer to tx_fes_setup tlv header
+ * @ppdu_info: pointer to hal_tx_ppdu_info
+ *
+ * Return: void
+ */
+static inline void
+hal_txmon_parse_tx_fes_setup(void *tx_tlv,
+			     struct hal_tx_ppdu_info *tx_ppdu_info)
+{
+	tx_ppdu_info->num_users = HAL_TX_DESC_GET(tx_tlv,
+						  TX_FES_SETUP,
+						  NUMBER_OF_USERS);
+}
+#endif
+
+/**
+ * hal_txmon_status_get_num_users_generic_be() - api to get num users
+ * from start of fes window
+ *
+ * @tx_tlv_hdr: pointer to TLV header
+ * @num_users: reference to number of user
+ *
+ * Return: status
+ */
+static inline uint32_t
+hal_txmon_status_get_num_users_generic_be(void *tx_tlv_hdr, uint8_t *num_users)
+{
+	uint32_t tlv_tag, user_id, tlv_len;
+	uint32_t tlv_status = HAL_MON_TX_STATUS_PPDU_NOT_DONE;
+	void *tx_tlv;
+
+	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(tx_tlv_hdr);
+	user_id = HAL_RX_GET_USER_TLV32_USERID(tx_tlv_hdr);
+	tlv_len = HAL_RX_GET_USER_TLV32_LEN(tx_tlv_hdr);
+
+	tx_tlv = (uint8_t *)tx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
+	/* window starts with either initiator or response */
+	switch (tlv_tag) {
+	case WIFITX_FES_SETUP_E:
+	{
+		*num_users = hal_txmon_get_num_users(tx_tlv);
+
+		tlv_status = HAL_MON_TX_FES_SETUP;
+		break;
+	}
+	case WIFIRX_RESPONSE_REQUIRED_INFO_E:
+	{
+		*num_users = HAL_TX_DESC_GET(tx_tlv,
+					     RX_RESPONSE_REQUIRED_INFO,
+					     RESPONSE_STA_COUNT);
+		tlv_status = HAL_MON_RX_RESPONSE_REQUIRED_INFO;
+		break;
+	}
+	};
+
+	return tlv_status;
+}
+
 /**
  * hal_txmon_free_status_buffer() - api to free status buffer
  * @pdev_handle: DP_PDEV handle
@@ -2602,6 +2712,124 @@ hal_txmon_status_free_buffer_generic_be(qdf_frag_t status_frag)
 			break;
 	} while (tlv_status == HAL_MON_TX_STATUS_PPDU_NOT_DONE);
 }
+
+/**
+ * hal_tx_get_ppdu_info() - api to get tx ppdu info
+ * @pdev_handle: DP_PDEV handle
+ * @prot_ppdu_info: populate dp_ppdu_info protection
+ * @tx_data_ppdu_info: populate dp_ppdu_info data
+ * @tlv_tag: Tag
+ *
+ * Return: dp_tx_ppdu_info pointer
+ */
+static inline void *
+hal_tx_get_ppdu_info(void *data_info, void *prot_info, uint32_t tlv_tag)
+{
+	struct hal_tx_ppdu_info *prot_ppdu_info = prot_info;
+
+	switch (tlv_tag) {
+	case WIFITX_FES_SETUP_E:/* DOWNSTREAM */
+	case WIFITX_FLUSH_E:/* DOWNSTREAM */
+	case WIFIPCU_PPDU_SETUP_INIT_E:/* DOWNSTREAM */
+	case WIFITX_PEER_ENTRY_E:/* DOWNSTREAM */
+	case WIFITX_QUEUE_EXTENSION_E:/* DOWNSTREAM */
+	case WIFITX_MPDU_START_E:/* DOWNSTREAM */
+	case WIFITX_MSDU_START_E:/* DOWNSTREAM */
+	case WIFITX_DATA_E:/* DOWNSTREAM */
+	case WIFIMON_BUFFER_ADDR_E:/* DOWNSTREAM */
+	case WIFITX_MPDU_END_E:/* DOWNSTREAM */
+	case WIFITX_MSDU_END_E:/* DOWNSTREAM */
+	case WIFITX_LAST_MPDU_FETCHED_E:/* DOWNSTREAM */
+	case WIFITX_LAST_MPDU_END_E:/* DOWNSTREAM */
+	case WIFICOEX_TX_REQ_E:/* DOWNSTREAM */
+	case WIFITX_RAW_OR_NATIVE_FRAME_SETUP_E:/* DOWNSTREAM */
+	case WIFINDP_PREAMBLE_DONE_E:/* DOWNSTREAM */
+	case WIFISCH_CRITICAL_TLV_REFERENCE_E:/* DOWNSTREAM */
+	case WIFITX_LOOPBACK_SETUP_E:/* DOWNSTREAM */
+	case WIFITX_FES_SETUP_COMPLETE_E:/* DOWNSTREAM */
+	case WIFITQM_MPDU_GLOBAL_START_E:/* DOWNSTREAM */
+	case WIFITX_WUR_DATA_E:/* DOWNSTREAM */
+	case WIFISCHEDULER_END_E:/* DOWNSTREAM */
+	{
+		return data_info;
+	}
+	}
+
+	/*
+	 * check current prot_tlv_status is start protection
+	 * check current tlv_tag is either start protection or end protection
+	 */
+	if (TXMON_HAL(prot_ppdu_info,
+		      prot_tlv_status) == WIFITX_FES_STATUS_START_PROT_E) {
+		return prot_info;
+	} else if (tlv_tag == WIFITX_FES_STATUS_PROT_E ||
+		   tlv_tag == WIFITX_FES_STATUS_START_PROT_E) {
+		TXMON_HAL(prot_ppdu_info, prot_tlv_status) = tlv_tag;
+		return prot_info;
+	} else {
+		return data_info;
+	}
+
+	return data_info;
+}
+
+/**
+ * hal_txmon_status_parse_tlv_generic_be() - api to parse status tlv.
+ * @data_ppdu_info: hal_txmon data ppdu info
+ * @prot_ppdu_info: hal_txmon prot ppdu info
+ * @data_status_info: pointer to data status info
+ * @prot_status_info: pointer to prot status info
+ * @tx_tlv_hdr: fragment of tx_tlv_hdr
+ * @status_frag: qdf_frag_t buffer
+ *
+ * Return: status
+ */
+static inline uint32_t
+hal_txmon_status_parse_tlv_generic_be(void *data_ppdu_info,
+				      void *prot_ppdu_info,
+				      void *data_status_info,
+				      void *prot_status_info,
+				      void *tx_tlv_hdr,
+				      qdf_frag_t status_frag)
+{
+	struct hal_tx_ppdu_info *tx_ppdu_info;
+	struct hal_tx_status_info *tx_status_info;
+	uint32_t tlv_tag, user_id, tlv_len;
+	qdf_frag_t frag_buf = NULL;
+	uint32_t status = HAL_MON_TX_STATUS_PPDU_NOT_DONE;
+	void *tx_tlv;
+
+	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(tx_tlv_hdr);
+	user_id = HAL_RX_GET_USER_TLV32_USERID(tx_tlv_hdr);
+	tlv_len = HAL_RX_GET_USER_TLV32_LEN(tx_tlv_hdr);
+
+	tx_tlv = (uint8_t *)tx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
+
+	tx_ppdu_info = hal_tx_get_ppdu_info(data_ppdu_info,
+					    prot_ppdu_info, tlv_tag);
+	tx_status_info = (tx_ppdu_info->is_data ? data_status_info :
+			  prot_status_info);
+
+	/* parse tlv and populate tx_ppdu_info */
+	switch (tlv_tag) {
+	case WIFIMON_BUFFER_ADDR_E:
+	{
+		frag_buf = hal_txmon_get_buffer_addr_generic_be(tx_tlv, NULL);
+		if (frag_buf)
+			qdf_frag_free(frag_buf);
+		frag_buf = NULL;
+		status = HAL_MON_TX_BUFFER_ADDR;
+		break;
+	}
+	case WIFITX_FES_STATUS_START_PROT_E:
+	{
+		TXMON_HAL(tx_ppdu_info, prot_tlv_status) = tlv_tag;
+		break;
+	}
+	}
+
+	return status;
+}
 #endif /* QCA_MONITOR_2_0_SUPPORT */
 
 #ifdef REO_SHARED_QREF_TABLE_EN

+ 8 - 0
hal/wifi3.0/hal_internal.h

@@ -1026,6 +1026,14 @@ struct hal_hw_txrx_ops {
 
 	/* TX MONITOR */
 #ifdef QCA_MONITOR_2_0_SUPPORT
+	uint32_t (*hal_txmon_status_parse_tlv)(void *data_ppdu_info,
+					       void *prot_ppdu_info,
+					       void *data_status_info,
+					       void *prot_status_info,
+					       void *tx_tlv_hdr,
+					       qdf_frag_t status_frag);
+	uint32_t (*hal_txmon_status_get_num_users)(void *tx_tlv_hdr,
+						   uint8_t *num_users);
 	void (*hal_txmon_status_free_buffer)(qdf_frag_t status_frag);
 #endif /* QCA_MONITOR_2_0_SUPPORT */
 	void (*hal_reo_shared_qaddr_setup)(hal_soc_handle_t hal_soc_hdl);

+ 9 - 0
hal/wifi3.0/qcn9224/hal_9224.c

@@ -1840,6 +1840,15 @@ static void hal_hw_txrx_ops_attach_qcn9224(struct hal_soc *hal_soc)
 	hal_soc->ops->hal_reo_shared_qaddr_detach = hal_reo_shared_qaddr_detach_be;
 	hal_soc->ops->hal_reo_shared_qaddr_write = hal_reo_shared_qaddr_write_be;
 #endif
+	/* TX MONITOR */
+#ifdef QCA_MONITOR_2_0_SUPPORT
+	hal_soc->ops->hal_txmon_status_parse_tlv =
+				hal_txmon_status_parse_tlv_generic_be;
+	hal_soc->ops->hal_txmon_status_get_num_users =
+				hal_txmon_status_get_num_users_generic_be;
+	hal_soc->ops->hal_txmon_status_free_buffer =
+				hal_txmon_status_free_buffer_generic_be;
+#endif /* QCA_MONITOR_2_0_SUPPORT */
 };
 
 struct hal_hw_srng_config hw_srng_table_9224[] = {

+ 39 - 1
hal/wifi3.0/qcn9224/hal_9224_tx.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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
@@ -16,6 +16,9 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
+#ifndef _HAL_9224_TX_H_
+#define _HAL_9224_TX_H_
+
 #include "tcl_data_cmd.h"
 #include "phyrx_rssi_legacy.h"
 #include "hal_internal.h"
@@ -189,3 +192,38 @@ hal_tx_init_cmd_credit_ring_9224(hal_soc_handle_t hal_soc_hdl,
 				 hal_ring_handle_t hal_ring_hdl)
 {
 }
+
+/* TX MONITOR */
+#ifdef QCA_MONITOR_2_0_SUPPORT
+
+#if defined(TX_MONITOR_WORD_MASK)
+typedef struct tx_fes_setup_compact_9224 hal_tx_fes_setup_t;
+struct tx_fes_setup_compact_9224 {
+	/* DWORD - 0 */
+	uint32_t schedule_id;
+	/* DWORD - 1 */
+	uint32_t reserved_1a			: 7,  // [0: 6]
+		transmit_start_reason		: 3,  // [7: 9]
+		reserved_1b			: 13, // [10: 22]
+		number_of_users			: 6,  // [28: 23]
+		MU_type				: 1,  // [29]
+		reserved_1c			: 2;  // [30]
+	/* DWORD - 2 */
+	uint32_t reserved_2a			: 4,  // [0: 3]
+		ndp_frame			: 2,  // [4: 5]
+		txbf				: 1,  // [6]
+		reserved_2b			: 3,  // [7: 9]
+		static_bandwidth		: 3,  // [12: 10]
+		reserved_2c			: 1,  // [13]
+		transmission_contains_MU_RTS	: 1,  // [14]
+		reserved_2d			: 17; // [15: 31]
+	/* DWORD - 3 */
+	uint32_t reserved_3a			: 15, // [0: 14]
+		mu_ndp				: 1,  // [15]
+		reserved_3b			: 11, // [16: 26]
+		ndpa				: 1,  // [27]
+		reserved_3c			: 4;  // [28: 31]
+};
+#endif
+#endif /* QCA_MONITOR_2_0_SUPPORT */
+#endif /* _HAL_9224_TX_H_ */