qcacmn: CFR: Process PPDU status TLVs and extract CFR information

Channel Frequency Response(CFR) feature requires PPDU information
for correlation with CFR data. Host subscribes for the relevant PPDU
status TLVs via the Host RX monitor status ring. During monitor status
ring reap, all information needed for CFR correlation is accumulated
in a HAL PPDU structure and delivered to WDI event subscribers.

Change-Id: I3662b60375cb8886447a2fba3efead6a1ef3a98d
CRs-Fixed: 2593408
diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h
index 607159f..cc874f0 100644
--- a/hal/wifi3.0/hal_api_mon.h
+++ b/hal/wifi3.0/hal_api_mon.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. 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
@@ -466,6 +466,83 @@
 	uint32_t flow_idx;
 };
 
+#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
+/**
+ * struct hal_rx_ppdu_cfr_user_info - struct for storing peer info extracted
+ * from HW TLVs, this will be used for correlating CFR data with multiple peers
+ * in MU PPDUs
+ *
+ * @peer_macaddr: macaddr of the peer
+ * @ast_index: AST index of the peer
+ */
+struct hal_rx_ppdu_cfr_user_info {
+	uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE];
+	uint32_t ast_index;
+};
+
+/**
+ * struct hal_rx_ppdu_cfr_info - struct for storing ppdu info extracted from HW
+ * TLVs, this will be used for CFR correlation
+ *
+ * @bb_captured_channel : Set by RXPCU when MACRX_FREEZE_CAPTURE_CHANNEL TLV is
+ * sent to PHY, SW checks it to correlate current PPDU TLVs with uploaded
+ * channel information.
+ *
+ * @bb_captured_timeout : Set by RxPCU to indicate channel capture condition is
+ * met, but MACRX_FREEZE_CAPTURE_CHANNEL is not sent to PHY due to AST delay,
+ * which means the rx_frame_falling edge to FREEZE TLV ready time exceeds
+ * the threshold time defined by RXPCU register FREEZE_TLV_DELAY_CNT_THRESH.
+ * Bb_captured_reason is still valid in this case.
+ *
+ * @rx_location_info_valid: Indicates whether CFR DMA address in the PPDU TLV
+ * is valid
+ * <enum 0 rx_location_info_is_not_valid>
+ * <enum 1 rx_location_info_is_valid>
+ * <legal all>
+ *
+ * @bb_captured_reason : Copy capture_reason of MACRX_FREEZE_CAPTURE_CHANNEL
+ * TLV to here for FW usage. Valid when bb_captured_channel or
+ * bb_captured_timeout is set.
+ * <enum 0 freeze_reason_TM>
+ * <enum 1 freeze_reason_FTM>
+ * <enum 2 freeze_reason_ACK_resp_to_TM_FTM>
+ * <enum 3 freeze_reason_TA_RA_TYPE_FILTER>
+ * <enum 4 freeze_reason_NDPA_NDP>
+ * <enum 5 freeze_reason_ALL_PACKET>
+ * <legal 0-5>
+ *
+ * @rtt_che_buffer_pointer_low32 : The low 32 bits of the 40 bits pointer to
+ * external RTT channel information buffer
+ *
+ * @rtt_che_buffer_pointer_high8 : The high 8 bits of the 40 bits pointer to
+ * external RTT channel information buffer
+ *
+ * @chan_capture_status : capture status reported by ucode
+ * a. CAPTURE_IDLE: FW has disabled "REPETITIVE_CHE_CAPTURE_CTRL"
+ * b. CAPTURE_BUSY: previous PPDU’s channel capture upload DMA ongoing. (Note
+ * that this upload is triggered after receiving freeze_channel_capture TLV
+ * after last PPDU is rx)
+ * c. CAPTURE_ACTIVE: channel capture is enabled and no previous channel
+ * capture ongoing
+ * d. CAPTURE_NO_BUFFER: next buffer in IPC ring not available
+ *
+ * @cfr_user_info: Peer mac for upto 4 MU users
+ */
+
+struct hal_rx_ppdu_cfr_info {
+	bool bb_captured_channel;
+	bool bb_captured_timeout;
+	uint8_t bb_captured_reason;
+	bool rx_location_info_valid;
+	uint8_t chan_capture_status;
+	uint8_t rtt_che_buffer_pointer_high8;
+	uint32_t rtt_che_buffer_pointer_low32;
+	struct hal_rx_ppdu_cfr_user_info cfr_user_info[HAL_MAX_UL_MU_USERS];
+};
+#else
+struct hal_rx_ppdu_cfr_info {};
+#endif
+
 struct hal_rx_ppdu_info {
 	struct hal_rx_ppdu_common_info com_info;
 	struct mon_rx_status rx_status;
@@ -490,6 +567,11 @@
 	struct hal_rx_msdu_payload_info ppdu_msdu_info[HAL_RX_MAX_MPDU];
 	/* evm info */
 	struct hal_rx_su_evm_info evm_info;
+	/**
+	 * Will be used to store ppdu info extracted from HW TLVs,
+	 * and for CFR correlation as well
+	 */
+	struct hal_rx_ppdu_cfr_info cfr_info;
 };
 
 static inline uint32_t
diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h
index 1c03f5a..05e110d 100644
--- a/hal/wifi3.0/hal_generic_api.h
+++ b/hal/wifi3.0/hal_generic_api.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -439,6 +439,10 @@
 		ppdu_info->rx_state = HAL_RX_MON_PPDU_END;
 		break;
 
+	case WIFIPHYRX_PKT_END_E:
+		hal_rx_get_rtt_info(hal_soc_hdl, rx_tlv, ppdu_info);
+		break;
+
 	case WIFIRXPCU_PPDU_END_INFO_E:
 		ppdu_info->rx_status.rx_antenna =
 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_2, RX_ANTENNA);
@@ -451,6 +455,7 @@
 		ppdu_info->rx_status.duration =
 			HAL_RX_GET(rx_tlv, UNIFIED_RXPCU_PPDU_END_INFO_8,
 				RX_PPDU_DURATION);
+		hal_rx_get_bb_info(hal_soc_hdl, rx_tlv, ppdu_info);
 		break;
 
 	/*
diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h
index c2773ff..6d863f1 100644
--- a/hal/wifi3.0/hal_internal.h
+++ b/hal/wifi3.0/hal_internal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -459,6 +459,8 @@
 					  uint32_t *flow_index);
 	uint16_t (*hal_rx_tlv_get_tcp_chksum)(uint8_t *buf);
 	uint16_t (*hal_rx_get_rx_sequence)(uint8_t *buf);
+	void (*hal_rx_get_bb_info)(void *rx_tlv, void *ppdu_info_handle);
+	void (*hal_rx_get_rtt_info)(void *rx_tlv, void *ppdu_info_handle);
 };
 
 /**
diff --git a/hal/wifi3.0/hal_rx.h b/hal/wifi3.0/hal_rx.h
index 430814b..2f8277b 100644
--- a/hal/wifi3.0/hal_rx.h
+++ b/hal/wifi3.0/hal_rx.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -3368,4 +3368,26 @@
 
 	return hal_soc->ops->hal_rx_get_rx_sequence(buf);
 }
+
+static inline void
+hal_rx_get_bb_info(hal_soc_handle_t hal_soc_hdl,
+		   void *rx_tlv,
+		   void *ppdu_info)
+{
+	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
+
+	if (hal_soc->ops->hal_rx_get_bb_info)
+		hal_soc->ops->hal_rx_get_bb_info(rx_tlv, ppdu_info);
+}
+
+static inline void
+hal_rx_get_rtt_info(hal_soc_handle_t hal_soc_hdl,
+		    void *rx_tlv,
+		    void *ppdu_info)
+{
+	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
+
+	if (hal_soc->ops->hal_rx_get_rtt_info)
+		hal_soc->ops->hal_rx_get_rtt_info(rx_tlv, ppdu_info);
+}
 #endif /* _HAL_RX_H */
diff --git a/hal/wifi3.0/qca6290/hal_6290.c b/hal/wifi3.0/qca6290/hal_6290.c
index a848e15..132dd76 100644
--- a/hal/wifi3.0/qca6290/hal_6290.c
+++ b/hal/wifi3.0/qca6290/hal_6290.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -1076,6 +1076,8 @@
 	hal_rx_msdu_get_flow_params_6290,
 	hal_rx_tlv_get_tcp_chksum_6290,
 	hal_rx_get_rx_sequence_6290,
+	NULL,
+	NULL,
 };
 
 struct hal_hw_srng_config hw_srng_table_6290[] = {
diff --git a/hal/wifi3.0/qca6390/hal_6390.c b/hal/wifi3.0/qca6390/hal_6390.c
index 56e7f3d..89dd612 100644
--- a/hal/wifi3.0/qca6390/hal_6390.c
+++ b/hal/wifi3.0/qca6390/hal_6390.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -1072,6 +1072,8 @@
 	hal_rx_msdu_get_flow_params_6390,
 	hal_rx_tlv_get_tcp_chksum_6390,
 	hal_rx_get_rx_sequence_6390,
+	NULL,
+	NULL,
 };
 
 struct hal_hw_srng_config hw_srng_table_6390[] = {
diff --git a/hal/wifi3.0/qca6490/hal_6490.c b/hal/wifi3.0/qca6490/hal_6490.c
index 7a349b0..6b889e1 100644
--- a/hal/wifi3.0/qca6490/hal_6490.c
+++ b/hal/wifi3.0/qca6490/hal_6490.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020 The Linux Foundation. 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
@@ -1391,6 +1391,8 @@
 	NULL,
 	hal_rx_tlv_get_tcp_chksum_6490,
 	hal_rx_get_rx_sequence_6490,
+	NULL,
+	NULL,
 };
 
 struct hal_hw_srng_config hw_srng_table_6490[] = {
diff --git a/hal/wifi3.0/qca8074v1/hal_8074v1.c b/hal/wifi3.0/qca8074v1/hal_8074v1.c
index d758b1f..303da11 100644
--- a/hal/wifi3.0/qca8074v1/hal_8074v1.c
+++ b/hal/wifi3.0/qca8074v1/hal_8074v1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -1072,6 +1072,8 @@
 	hal_rx_msdu_get_flow_params_8074v1,
 	hal_rx_tlv_get_tcp_chksum_8074v1,
 	hal_rx_get_rx_sequence_8074v1,
+	NULL,
+	NULL,
 };
 
 struct hal_hw_srng_config hw_srng_table_8074[] = {
diff --git a/hal/wifi3.0/qca8074v2/hal_8074v2.c b/hal/wifi3.0/qca8074v2/hal_8074v2.c
index 61f5cc7..6a3462a 100644
--- a/hal/wifi3.0/qca8074v2/hal_8074v2.c
+++ b/hal/wifi3.0/qca8074v2/hal_8074v2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -1071,6 +1071,14 @@
 	hal_rx_msdu_get_flow_params_8074v2,
 	hal_rx_tlv_get_tcp_chksum_8074v2,
 	hal_rx_get_rx_sequence_8074v2,
+#if defined(QCA_WIFI_QCA6018) && defined(WLAN_CFR_ENABLE) && \
+	defined(WLAN_ENH_CFR_ENABLE)
+	hal_rx_get_bb_info_8074v2,
+	hal_rx_get_rtt_info_8074v2,
+#else
+	NULL,
+	NULL,
+#endif
 };
 
 struct hal_hw_srng_config hw_srng_table_8074v2[] = {
diff --git a/hal/wifi3.0/qca8074v2/hal_8074v2_rx.h b/hal/wifi3.0/qca8074v2/hal_8074v2_rx.h
index 2c7ed76..502808e 100644
--- a/hal/wifi3.0/qca8074v2/hal_8074v2_rx.h
+++ b/hal/wifi3.0/qca8074v2/hal_8074v2_rx.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -500,6 +500,51 @@
 }
 #endif
 
+#if defined(QCA_WIFI_QCA6018) && defined(WLAN_CFR_ENABLE) && \
+	defined(WLAN_ENH_CFR_ENABLE)
+static inline
+void hal_rx_get_bb_info_8074v2(void *rx_tlv,
+			       void *ppdu_info_hdl)
+{
+	struct hal_rx_ppdu_info *ppdu_info  = ppdu_info_hdl;
+
+	ppdu_info->cfr_info.bb_captured_channel =
+	  HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_CHANNEL);
+
+	ppdu_info->cfr_info.bb_captured_timeout =
+	  HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_TIMEOUT);
+
+	ppdu_info->cfr_info.bb_captured_reason =
+	  HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_3, BB_CAPTURED_REASON);
+}
+
+static inline
+void hal_rx_get_rtt_info_8074v2(void *rx_tlv,
+				void *ppdu_info_hdl)
+{
+	struct hal_rx_ppdu_info *ppdu_info  = ppdu_info_hdl;
+
+	ppdu_info->cfr_info.rx_location_info_valid =
+		HAL_RX_GET(rx_tlv, PHYRX_PKT_END_13_RX_PKT_END_DETAILS,
+			   RX_LOCATION_INFO_DETAILS_RX_LOCATION_INFO_VALID);
+
+	ppdu_info->cfr_info.rtt_che_buffer_pointer_low32 =
+	HAL_RX_GET(rx_tlv,
+		   PHYRX_PKT_END_12_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS,
+		   RTT_CHE_BUFFER_POINTER_LOW32);
+
+	ppdu_info->cfr_info.rtt_che_buffer_pointer_high8 =
+	HAL_RX_GET(rx_tlv,
+		   PHYRX_PKT_END_11_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS,
+		   RTT_CHE_BUFFER_POINTER_HIGH8);
+
+	ppdu_info->cfr_info.chan_capture_status =
+	HAL_RX_GET(rx_tlv,
+		   PHYRX_PKT_END_13_RX_PKT_END_DETAILS_RX_LOCATION_INFO_DETAILS,
+		   RESERVED_8);
+}
+#endif
+
 /**
  * hal_rx_dump_msdu_start_tlv_8074v2() : dump RX msdu_start TLV in structured
  *			     human readable format.
diff --git a/hal/wifi3.0/qcn9000/hal_9000.c b/hal/wifi3.0/qcn9000/hal_9000.c
index 805acdd..c07ad16 100644
--- a/hal/wifi3.0/qcn9000/hal_9000.c
+++ b/hal/wifi3.0/qcn9000/hal_9000.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. 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
@@ -1431,6 +1431,8 @@
 	hal_rx_msdu_get_flow_params_9000,
 	hal_rx_tlv_get_tcp_chksum_9000,
 	hal_rx_get_rx_sequence_9000,
+	NULL,
+	NULL,
 };
 
 struct hal_hw_srng_config hw_srng_table_9000[] = {