Explorar o código

qcacmn: change to configure and handle undecoded metadata capture

Added change:
1. Set/reset RXDMA MON STATUS ring filter setting and send HTT
   message to capture undecoded frame
2. Handle undecoded frame to update cdp_rx_indication_ppdu structure
   from hal ppdu_info rx status and generate WDI event to deliver it
   to upper layer

Change-Id: I14485f28333b113b5a2fab639611551c2b08af2b
Basamma Yakkanahalli %!s(int64=3) %!d(string=hai) anos
pai
achega
e85fbce095

+ 69 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -1185,6 +1185,7 @@ enum cdp_peer_param_type {
  * @CDP_CONFIG_SPECIAL_VAP: Configure Special vap
  * @CDP_RESET_SCAN_SPCL_VAP_STATS_ENABLE: Enable scan spcl vap stats reset
  * @CDP_ISOLATION: set isolation flag
+ * @CDP_CONFIG_UNDECODED_METADATA_CAPTURE_ENABLE: Undecoded metadata capture
  */
 enum cdp_pdev_param_type {
 	CDP_CONFIG_DEBUG_SNIFFER,
@@ -1219,6 +1220,7 @@ enum cdp_pdev_param_type {
 	CDP_RESET_SCAN_SPCL_VAP_STATS_ENABLE,
 	CDP_CONFIG_ENHANCED_STATS_ENABLE,
 	CDP_ISOLATION,
+	CDP_CONFIG_UNDECODED_METADATA_CAPTURE_ENABLE,
 };
 
 /*
@@ -1289,6 +1291,7 @@ enum cdp_pdev_param_type {
  * @cdp_psoc_param_en_nss_cfg: set nss cfg
  * @cdp_ipa_enabled : set ipa mode
  * @cdp_psoc_param_vdev_stats_hw_offload: Configure HW vdev stats offload
+ * @cdp_pdev_param_undecoded_metadata_enable: Undecoded metadata capture enable
  */
 typedef union cdp_config_param_t {
 	/* peer params */
@@ -1370,6 +1373,7 @@ typedef union cdp_config_param_t {
 	bool cdp_skip_bar_update;
 	bool cdp_ipa_enabled;
 	bool cdp_psoc_param_vdev_stats_hw_offload;
+	bool cdp_pdev_param_undecoded_metadata_enable;
 	bool cdp_sawf_enabled;
 } cdp_config_param_type;
 
@@ -2364,6 +2368,37 @@ struct cdp_rx_stats_ppdu_user {
  * @nf: noise floor
  * @per_chain_rssi: rssi per antenna
  * @punc_bw: puncered bw
+ * @phyrx_abort: rx aborted undecoded frame indication
+ * @phyrx_abort_reason: abort reason defined in phyrx_abort_request_info
+ * @l_sig_length: L SIG A length
+ * @l_sig_a_parity: L SIG A parity
+ * @l_sig_a_pkt_type: L SIG A info pkt type
+ * @l_sig_a_implicit_sounding: L SIG A info captured implicit sounding
+ * @ht_length: num of bytes in PSDU
+ * @ht_smoothing: Indicate ht_smoothing
+ * @ht_not_sounding: Indicate ht not sounding
+ * @ht_aggregation: Indicate ht aggregation
+ * @ht_stbc: Indicate ht stbc
+ * @ht_crc: Indicate ht crc
+ * @vht_crc: Indicate vht crc
+ * @vht_no_txop_ps: Indicate TXOP power save mode
+ * @bss_color_id: Indicate BSS color ID
+ * @beam_change: Indicates whether spatial mapping is changed
+ * @dl_ul_flag: Differentiates between DL and UL transmission
+ * @transmit_mcs: Indicates the data MCS
+ * @ldpc_extra_sym: LDPC extra symbol
+ * @special_reuse: Spatial reuse
+ * @ltf_sym: Indictaes HE NSTS
+ * @txbf: Indicates whether beamforming is applied
+ * @pe_disambiguity: packet extension disambiguity
+ * @pre_fec_pad: packet extension a factor
+ * @dopplar: Doppler support
+ * @txop_duration: Indicates the remaining time in the current TXOP
+ * @sig_b_mcs: MCS of HE-SIG-B
+ * @sig_b_dcm: DCM of HE-SIG-B
+ * @sig_b_sym: Number of symbols of HE-SIG-B
+ * @sig_b_comp: Compression mode of HE-SIG-B
+ * @he_crc: CRC for HE-SIG contents
  */
 struct cdp_rx_indication_ppdu {
 	uint32_t ppdu_id;
@@ -2425,6 +2460,40 @@ struct cdp_rx_indication_ppdu {
 	struct cdp_rx_ppdu_cfr_info cfr_info;
 #endif
 	uint8_t punc_bw;
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	bool phyrx_abort;
+	uint8_t phyrx_abort_reason;
+	uint32_t l_sig_length:12,
+		 l_sig_a_parity:1,
+		 l_sig_a_pkt_type:4,
+		 l_sig_a_implicit_sounding:1,
+		 vht_crc:8,
+		 group_id:6;
+	uint32_t ht_length:16,
+		 ht_smoothing:1,
+		 ht_not_sounding:1,
+		 ht_aggregation:1,
+		 ht_stbc:2,
+		 ht_crc:8,
+		 vht_no_txop_ps:1;
+	uint32_t bss_color_id:6,
+		 beam_change:1,
+		 dl_ul_flag:1,
+		 transmit_mcs:4,
+		 ldpc_extra_sym:1,
+		 special_reuse:4,
+		 ltf_sym:3,
+		 txbf:1,
+		 pe_disambiguity:1,
+		 pre_fec_pad:4,
+		 dopplar:1;
+	uint32_t txop_duration:7,
+		 sig_b_mcs:3,
+		 sig_b_dcm:1,
+		 sig_b_sym:4,
+		 sig_b_comp:1,
+		 he_crc:4;
+#endif
 };
 
 /**

+ 3 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -700,6 +700,9 @@ enum WDI_EVENT {
 	WDI_EVENT_HYBRID_TX,
 #ifdef WLAN_FEATURE_11BE_MLO
 	WDI_EVENT_MLO_TSTMP,
+#endif
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	WDI_EVENT_RX_PPDU_DESC_UNDECODED_METADATA,
 #endif
 	/* End of new event items */
 	WDI_EVENT_LAST

+ 54 - 2
dp/wifi3.0/dp_htt.c

@@ -866,6 +866,51 @@ int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
 qdf_export_symbol(htt_h2t_full_mon_cfg);
 #endif
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+static inline void
+dp_mon_rx_enable_phy_errors(uint32_t *msg_word,
+			    struct htt_rx_ring_tlv_filter *htt_tlv_filter)
+{
+	if (htt_tlv_filter->phy_err_filter_valid) {
+		HTT_RX_RING_SELECTION_CFG_FP_PHY_ERR_SET
+			(*msg_word, htt_tlv_filter->fp_phy_err);
+		HTT_RX_RING_SELECTION_CFG_FP_PHY_ERR_BUF_SRC_SET
+			(*msg_word, htt_tlv_filter->fp_phy_err_buf_src);
+		HTT_RX_RING_SELECTION_CFG_FP_PHY_ERR_BUF_DEST_SET
+			(*msg_word, htt_tlv_filter->fp_phy_err_buf_dest);
+
+		/* word 12*/
+		msg_word++;
+		*msg_word = 0;
+		HTT_RX_RING_SELECTION_CFG_PHY_ERR_MASK_SET
+			(*msg_word, htt_tlv_filter->phy_err_mask);
+
+		/* word 13*/
+		msg_word++;
+		*msg_word = 0;
+		HTT_RX_RING_SELECTION_CFG_PHY_ERR_MASK_CONT_SET
+			(*msg_word, htt_tlv_filter->phy_err_mask_cont);
+
+		/* word 14*/
+		msg_word++;
+		*msg_word = 0;
+	} else {
+		/* word 14*/
+		msg_word += 3;
+		*msg_word = 0;
+	}
+}
+#else
+static inline void
+dp_mon_rx_enable_phy_errors(uint32_t *msg_word,
+			    struct htt_rx_ring_tlv_filter *htt_tlv_filter)
+{
+	/* word 14*/
+	msg_word += 3;
+	*msg_word = 0;
+}
+#endif
+
 /*
  * htt_h2t_rx_ring_cfg() - Send SRNG packet and TLV filter
  * config message to target
@@ -1534,6 +1579,7 @@ int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id,
 
 	HTT_RX_RING_SELECTION_CFG_TLV_FILTER_IN_FLAG_SET(*msg_word, tlv_filter);
 
+	/* word 7 */
 	msg_word++;
 	*msg_word = 0;
 	if (htt_tlv_filter->offset_valid) {
@@ -1542,6 +1588,7 @@ int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id,
 		HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET_SET(*msg_word,
 					htt_tlv_filter->rx_header_offset);
 
+		/* word 8 */
 		msg_word++;
 		*msg_word = 0;
 		HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET_SET(*msg_word,
@@ -1549,6 +1596,7 @@ int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id,
 		HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET_SET(*msg_word,
 					htt_tlv_filter->rx_mpdu_start_offset);
 
+		/* word 9 */
 		msg_word++;
 		*msg_word = 0;
 		HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET_SET(*msg_word,
@@ -1556,13 +1604,17 @@ int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id,
 		HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET_SET(*msg_word,
 					htt_tlv_filter->rx_msdu_start_offset);
 
+		/* word 10 */
 		msg_word++;
 		*msg_word = 0;
 		HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET_SET(*msg_word,
 					htt_tlv_filter->rx_attn_offset);
+
+		/* word 11 */
 		msg_word++;
 		*msg_word = 0;
 	} else {
+		/* word 11 */
 		msg_word += 4;
 		*msg_word = 0;
 	}
@@ -1572,8 +1624,8 @@ int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id,
 								mon_drop_th);
 	dp_mon_rx_enable_mpdu_logging(soc->dp_soc, msg_word, htt_tlv_filter);
 
-	msg_word++;
-	*msg_word = 0;
+	dp_mon_rx_enable_phy_errors(msg_word, htt_tlv_filter);
+
 	dp_mon_rx_wmask_subscribe(soc->dp_soc, msg_word, htt_tlv_filter);
 
 	/* "response_required" field should be set if a HTT response message is

+ 15 - 0
dp/wifi3.0/dp_htt.h

@@ -597,6 +597,13 @@ struct htt_tx_ring_tlv_filter {
  * @rx_msdu_end_offset: Offset of rx_msdu_end tlv
  * @rx_msdu_start_offset: Offset of rx_msdu_start tlv
  * @rx_attn_offset: Offset of rx_attention tlv
+ * @fp_phy_err: Flag to indicate FP PHY status tlv
+ * @fp_phy_err_buf_src: source ring selection for the FP PHY ERR status tlv
+ * @fp_phy_err_buf_dest: dest ring selection for the FP PHY ERR status tlv
+ * @phy_err_mask: select the phy errors defined in phyrx_abort_request_reason
+ *  enums 0 to 31.
+ * @phy_err_mask_cont: select the fp phy errors defined in
+ *  phyrx_abort_request_reason enums 32 to 63
  * @rx_mpdu_start_wmask: word mask for mpdu start tlv
  * @rx_mpdu_end_wmask: word mask for mpdu end tlv
  * @rx_msdu_end_tlv: word mask for msdu end tlv
@@ -645,6 +652,14 @@ struct htt_rx_ring_tlv_filter {
 	uint16_t rx_msdu_end_offset;
 	uint16_t rx_msdu_start_offset;
 	uint16_t rx_attn_offset;
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	u_int32_t fp_phy_err:1,
+		fp_phy_err_buf_src:2,
+		fp_phy_err_buf_dest:2,
+		phy_err_filter_valid:1;
+	u_int32_t phy_err_mask;
+	u_int32_t phy_err_mask_cont;
+#endif
 #ifdef QCA_MONITOR_2_0_SUPPORT
 	uint16_t rx_mpdu_start_wmask;
 	uint16_t rx_mpdu_end_wmask;

+ 4 - 0
dp/wifi3.0/dp_main.c

@@ -9620,6 +9620,10 @@ static QDF_STATUS dp_set_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id,
 	case CDP_ISOLATION:
 		pdev->isolation = val.cdp_pdev_param_isolation;
 		break;
+	case CDP_CONFIG_UNDECODED_METADATA_CAPTURE_ENABLE:
+		return dp_monitor_config_undecoded_metadata_capture(pdev,
+				val.cdp_pdev_param_undecoded_metadata_enable);
+		break;
 	default:
 		return QDF_STATUS_E_INVAL;
 	}

+ 8 - 0
dp/wifi3.0/monitor/1.0/dp_mon_1.0.c

@@ -982,6 +982,14 @@ dp_mon_register_feature_ops_1_0(struct dp_soc *soc)
 	mon_ops->mon_rx_populate_ppdu_usr_info = NULL;
 	mon_ops->mon_rx_populate_ppdu_info = dp_mon_populate_ppdu_info_1_0;
 #endif
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	mon_ops->mon_config_undecoded_metadata_capture =
+		dp_mon_config_undecoded_metadata_capture;
+	mon_ops->mon_filter_setup_undecoded_metadata_capture =
+		dp_mon_filter_setup_undecoded_metadata_capture_1_0;
+	mon_ops->mon_filter_reset_undecoded_metadata_capture =
+		dp_mon_filter_reset_undecoded_metadata_capture_1_0;
+#endif
 }
 
 struct dp_mon_ops monitor_ops_1_0 = {

+ 74 - 0
dp/wifi3.0/monitor/1.0/dp_mon_filter_1.0.c

@@ -179,6 +179,80 @@ void dp_mon_filter_reset_enhanced_stats_1_0(struct dp_pdev *pdev)
 }
 #endif /* QCA_ENHANCED_STATS_SUPPORT */
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+/**
+ * mon_filter_setup_undecoded_metadata_capture() - Setup undecoded frame
+ * capture phyrx aborted frame filter setup
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_undecoded_metadata_capture_1_0(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode =
+				DP_MON_FILTER_UNDECODED_METADATA_CAPTURE_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	struct dp_mon_pdev *mon_pdev;
+
+	if (!pdev) {
+		dp_mon_filter_err("pdev Context is null");
+		return;
+	}
+
+	/* Enabled the filter */
+	filter.valid = true;
+
+	mon_pdev = pdev->monitor_pdev;
+	dp_mon_filter_set_status_cmn(mon_pdev, &filter);
+
+	/* Setup the filter to subscribe to FP PHY status tlv */
+	filter.tlv_filter.fp_phy_err = 1;
+	filter.tlv_filter.fp_phy_err_buf_src = SW2RXDMA_BUF_SOURCE_RING;
+	filter.tlv_filter.fp_phy_err_buf_dest = RXDMA2SW_RING;
+
+	filter.tlv_filter.phy_err_filter_valid = 1;
+
+	dp_mon_filter_show_filter(mon_pdev, mode, &filter);
+	mon_pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * mon_filter_reset_undecoded_metadata_capture() - Reset undecoded frame
+ * capture phyrx aborted frame filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_undecoded_metadata_capture_1_0(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode =
+				DP_MON_FILTER_UNDECODED_METADATA_CAPTURE_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	struct dp_mon_pdev *mon_pdev;
+
+	if (!pdev) {
+		dp_mon_filter_err("pdev Context is null");
+		return;
+	}
+	mon_pdev = pdev->monitor_pdev;
+
+	/* Enabled filter to reset to default values */
+	filter.valid = true;
+	/* Reset the filter and phy error mask */
+	filter.tlv_filter.fp_phy_err = 0;
+	filter.tlv_filter.fp_phy_err_buf_src = NO_BUFFER_RING;
+	filter.tlv_filter.fp_phy_err_buf_dest = RXDMA_RELEASING_RING;
+
+	filter.tlv_filter.phy_err_mask = 0;
+	filter.tlv_filter.phy_err_mask_cont = 0;
+
+	filter.tlv_filter.phy_err_filter_valid = 1;
+
+	dp_mon_filter_show_filter(mon_pdev, mode, &filter);
+	mon_pdev->filter[mode][srng_type] = filter;
+}
+#endif /* QCA_UNDECODED_METADATA_SUPPORT */
+
 #ifdef QCA_MCOPY_SUPPORT
 #ifdef QCA_MONITOR_PKT_SUPPORT
 static void dp_mon_filter_set_reset_mcopy_dest(struct dp_pdev *pdev,

+ 26 - 0
dp/wifi3.0/monitor/1.0/dp_mon_filter_1.0.h

@@ -39,6 +39,32 @@ static inline void dp_mon_filter_reset_enhanced_stats_1_0(struct dp_pdev *pdev)
 }
 #endif
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+/*
+ * dp_mon_filter_setup_undecoded_metadata_capture() - Setup the filter
+ * for undecoded metadata capture
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_undecoded_metadata_capture_1_0(struct dp_pdev *pdev);
+
+/*
+ * dp_mon_filter_reset_undecoded_metadata_capture() - Reset the filter
+ * for undecoded metadata capture
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_undecoded_metadata_capture_1_0(struct dp_pdev *pdev);
+#else
+static inline void
+dp_mon_filter_setup_undecoded_metadata_capture_1_0(struct dp_pdev *pdev)
+{
+}
+
+static inline void
+dp_mon_filter_reset_undecoded_metadata_capture_1_0(struct dp_pdev *pdev)
+{
+}
+#endif /* QCA_UNDECODED_METADATA_SUPPORT */
+
 #ifdef QCA_MCOPY_SUPPORT
 /**
  * dp_mon_filter_setup_mcopy_mode() - Setup the m_copy mode filter

+ 42 - 2
dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c

@@ -241,6 +241,41 @@ dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info)
 }
 #endif
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+static inline bool
+dp_rx_mon_check_phyrx_abort(struct dp_pdev *pdev,
+			    struct hal_rx_ppdu_info *ppdu_info)
+{
+	return (pdev->monitor_pdev->undecoded_metadata_capture &&
+			ppdu_info->rx_status.phyrx_abort);
+}
+
+static inline void
+dp_rx_mon_handle_ppdu_undecoded_metadata(struct dp_soc *soc,
+					 struct dp_pdev *pdev,
+					 struct hal_rx_ppdu_info *ppdu_info)
+{
+	if (pdev->monitor_pdev->undecoded_metadata_capture)
+		dp_rx_handle_ppdu_undecoded_metadata(soc, pdev, ppdu_info);
+
+	pdev->monitor_pdev->mon_ppdu_status = DP_PPDU_STATUS_START;
+}
+#else
+static inline bool
+dp_rx_mon_check_phyrx_abort(struct dp_pdev *pdev,
+			    struct hal_rx_ppdu_info *ppdu_info)
+{
+	return false;
+}
+
+static inline void
+dp_rx_mon_handle_ppdu_undecoded_metadata(struct dp_soc *soc,
+					 struct dp_pdev *pdev,
+					 struct hal_rx_ppdu_info *ppdu_info)
+{
+}
+#endif
+
 #ifdef QCA_SUPPORT_SCAN_SPCL_VAP_STATS
 /**
  * dp_rx_mon_update_scan_spcl_vap_stats() - Update special vap stats
@@ -296,7 +331,7 @@ dp_rx_mon_update_scan_spcl_vap_stats(struct dp_pdev *pdev,
 
 /**
  * dp_rx_mon_status_process_tlv() - Process status TLV in status
- *	buffer on Rx status Queue posted by status SRNG processing.
+ * buffer on Rx status Queue posted by status SRNG processing.
  * @soc: core txrx main context
  * @int_ctx: interrupt context
  * @mac_id: mac_id which is one of 3 mac_ids _ring
@@ -351,6 +386,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, struct dp_intr *int_ctx,
 
 		if ((mon_pdev->mvdev) || (mon_pdev->enhanced_stats_en) ||
 		    (mon_pdev->mcopy_mode) || (dp_cfr_rcc_mode_status(pdev)) ||
+		    (mon_pdev->undecoded_metadata_capture) ||
 		    (rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED)) {
 			do {
 				tlv_status = hal_rx_status_get_tlv_info(rx_tlv,
@@ -423,7 +459,8 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, struct dp_intr *int_ctx,
 
 		if (tlv_status == HAL_TLV_STATUS_PPDU_NON_STD_DONE) {
 			dp_rx_mon_deliver_non_std(soc, mac_id);
-		} else if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) {
+		} else if ((tlv_status == HAL_TLV_STATUS_PPDU_DONE) &&
+				(!dp_rx_mon_check_phyrx_abort(pdev, ppdu_info))) {
 			rx_mon_stats->status_ppdu_done++;
 			dp_rx_mon_handle_mu_ul_info(ppdu_info);
 
@@ -467,6 +504,9 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, struct dp_intr *int_ctx,
 						       quota);
 
 			mon_pdev->mon_ppdu_status = DP_PPDU_STATUS_START;
+		} else {
+			dp_rx_mon_handle_ppdu_undecoded_metadata(soc, pdev,
+								 ppdu_info);
 		}
 	}
 	return;

+ 8 - 0
dp/wifi3.0/monitor/2.0/dp_mon_2.0.c

@@ -1110,6 +1110,14 @@ dp_mon_register_feature_ops_2_0(struct dp_soc *soc)
 			dp_rx_mon_populate_ppdu_usr_info_2_0;
 	mon_ops->mon_rx_populate_ppdu_info = dp_rx_mon_populate_ppdu_info_2_0;
 #endif
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	mon_ops->mon_config_undecoded_metadata_capture =
+		dp_mon_config_undecoded_metadata_capture;
+	mon_ops->mon_filter_setup_undecoded_metadata_capture =
+		dp_mon_filter_setup_undecoded_metadata_capture_2_0;
+	mon_ops->mon_filter_reset_undecoded_metadata_capture =
+		dp_mon_filter_reset_undecoded_metadata_capture_2_0;
+#endif
 }
 
 struct dp_mon_ops monitor_ops_2_0 = {

+ 12 - 0
dp/wifi3.0/monitor/2.0/dp_mon_filter_2.0.c

@@ -1040,6 +1040,18 @@ void dp_mon_filter_reset_enhanced_stats_2_0(struct dp_pdev *pdev)
 }
 #endif /* QCA_ENHANCED_STATS_SUPPORT */
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+void
+dp_mon_filter_setup_undecoded_metadata_capture_2_0(struct dp_pdev *pdev)
+{
+}
+
+void
+dp_mon_filter_reset_undecoded_metadata_capture_2_0(struct dp_pdev *pdev)
+{
+}
+#endif
+
 #ifdef QCA_MCOPY_SUPPORT
 void dp_mon_filter_setup_mcopy_mode_2_0(struct dp_pdev *pdev)
 {

+ 26 - 0
dp/wifi3.0/monitor/2.0/dp_mon_filter_2.0.h

@@ -82,6 +82,32 @@ dp_mon_filter_reset_enhanced_stats_2_0(struct dp_pdev *pdev)
 }
 #endif
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+/*
+ * dp_mon_filter_setup_undecoded_metadata_capture() - Setup the filter
+ * for undecoded metadata capture
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_undecoded_metadata_capture_2_0(struct dp_pdev *pdev);
+
+/*
+ * dp_mon_filter_reset_undecoded_metadata_capture() - Reset the filter
+ * for undecoded metadata capture
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_undecoded_metadata_capture_2_0(struct dp_pdev *pdev);
+#else
+static inline void
+dp_mon_filter_setup_undecoded_metadata_capture_2_0(struct dp_pdev *pdev)
+{
+}
+
+static inline void
+dp_mon_filter_reset_undecoded_metadata_capture_2_0(struct dp_pdev *pdev)
+{
+}
+#endif
+
 #ifdef QCA_MCOPY_SUPPORT
 /**
  * dp_mon_filter_setup_mcopy_mode() - Setup the m_copy mode filter

+ 88 - 1
dp/wifi3.0/monitor/dp_mon.c

@@ -133,6 +133,69 @@ dp_config_mcopy_mode(struct dp_pdev *pdev, int val)
 }
 #endif /* QCA_MCOPY_SUPPORT */
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+static QDF_STATUS
+dp_reset_undecoded_metadata_capture(struct dp_pdev *pdev)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
+
+	if (mon_pdev->undecoded_metadata_capture) {
+		dp_mon_filter_reset_undecoded_metadata_mode(pdev);
+		status = dp_mon_filter_update(pdev);
+		if (status != QDF_STATUS_SUCCESS) {
+			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Undecoded capture filter reset failed"));
+		}
+		mon_pdev->monitor_configured = false;
+	}
+	mon_pdev->undecoded_metadata_capture = 0;
+	return status;
+}
+
+static QDF_STATUS
+dp_enable_undecoded_metadata_capture(struct dp_pdev *pdev, int val)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
+	struct dp_mon_ops *mon_ops;
+
+	if (!mon_pdev->mvdev) {
+		qdf_err("monitor_pdev is NULL");
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	mon_pdev->undecoded_metadata_capture = val;
+	mon_pdev->monitor_configured = true;
+
+	mon_ops = dp_mon_ops_get(pdev->soc);
+
+	/* Setup the undecoded metadata capture mode filter. */
+	dp_mon_filter_setup_undecoded_metadata_mode(pdev);
+	status = dp_mon_filter_update(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to set Undecoded capture filters"));
+		dp_mon_filter_reset_undecoded_metadata_mode(pdev);
+		return status;
+	}
+
+	return status;
+}
+#else
+static inline QDF_STATUS
+dp_reset_undecoded_metadata_capture(struct dp_pdev *pdev)
+{
+	return QDF_STATUS_E_INVAL;
+}
+
+static inline QDF_STATUS
+dp_enable_undecoded_metadata_capture(struct dp_pdev *pdev, int val)
+{
+	return QDF_STATUS_E_INVAL;
+}
+#endif /* QCA_UNDECODED_METADATA_SUPPORT */
+
 QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
 				 uint8_t pdev_id,
 				 uint8_t special_monitor)
@@ -171,10 +234,13 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
 #if defined(ATH_SUPPORT_NAC)
 		dp_mon_filter_reset_smart_monitor(pdev);
 #endif /* ATH_SUPPORT_NAC */
+	} else if (mon_pdev->undecoded_metadata_capture) {
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+		dp_reset_undecoded_metadata_capture(pdev);
+#endif
 	} else {
 		dp_mon_filter_reset_mon_mode(pdev);
 	}
-
 	status = dp_mon_filter_update(pdev);
 	if (status != QDF_STATUS_SUCCESS) {
 		dp_rx_mon_dest_err("%pK: Failed to reset monitor filters",
@@ -540,6 +606,27 @@ dp_config_debug_sniffer(struct dp_pdev *pdev, int val)
 }
 #endif
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+QDF_STATUS
+dp_mon_config_undecoded_metadata_capture(struct dp_pdev *pdev, int val)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
+
+	if (!mon_pdev->mvdev && !mon_pdev->scan_spcl_vap_configured) {
+		qdf_err("No monitor or Special vap, undecoded capture not supported");
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	if (val)
+		status = dp_enable_undecoded_metadata_capture(pdev, val);
+	else
+		status = dp_reset_undecoded_metadata_capture(pdev);
+
+	return status;
+}
+#endif
+
 /**
  * dp_monitor_mode_ring_config() - Send the tlv config to fw for monitor buffer
  *                                 ring based on target

+ 63 - 1
dp/wifi3.0/monitor/dp_mon.h

@@ -343,6 +343,23 @@ dp_config_debug_sniffer(struct dp_pdev *pdev, int val) {
 }
 #endif /* QCA_MCOPY_SUPPORT || QCA_TX_CAPTURE_SUPPORT */
 
+/*
+ * dp_config_debug_sniffer()- API to enable/disable debug sniffer
+ * @pdev: DP_PDEV handle
+ * @val: user provided value
+ *
+ * Return: 0 for success. nonzero for failure.
+ */
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+QDF_STATUS
+dp_mon_config_undecoded_metadata_capture(struct dp_pdev *pdev, int val);
+#else
+static inline QDF_STATUS
+dp_mon_config_undecoded_metadata_capture(struct dp_pdev *pdev, int val) {
+	return QDF_STATUS_E_INVAL;
+}
+#endif /* QCA_UNDECODED_METADATA_SUPPORT */
+
 /*
  * dp_htt_ppdu_stats_attach() - attach resources for HTT PPDU stats processing
  * @pdev: Datapath PDEV handle
@@ -720,7 +737,14 @@ struct dp_mon_ops {
 #endif
 	QDF_STATUS (*rx_mon_refill_buf_ring)(struct dp_intr *int_ctx);
 	QDF_STATUS (*tx_mon_refill_buf_ring)(struct dp_intr *int_ctx);
-
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	QDF_STATUS (*mon_config_undecoded_metadata_capture)
+	    (struct dp_pdev *pdev, int val);
+	void (*mon_filter_setup_undecoded_metadata_capture)
+	    (struct dp_pdev *pdev);
+	void (*mon_filter_reset_undecoded_metadata_capture)
+	    (struct dp_pdev *pdev);
+#endif
 };
 
 struct dp_mon_soc {
@@ -976,6 +1000,7 @@ struct  dp_mon_pdev {
 	bool is_dp_mon_pdev_initialized;
 	/* indicates if spcl vap is configured */
 	bool scan_spcl_vap_configured;
+	bool undecoded_metadata_capture;
 #ifdef QCA_SUPPORT_SCAN_SPCL_VAP_STATS
 	/* enable spcl vap stats reset on ch change */
 	bool reset_scan_spcl_vap_stats_enable;
@@ -1982,6 +2007,43 @@ static inline void dp_monitor_flush_rings(struct dp_soc *soc)
 	return monitor_ops->mon_flush_rings(soc);
 }
 
+/*
+ * dp_monitor_config_undecoded_metadata_capture() - Monitor config
+ * undecoded metatdata capture
+ * @pdev: point to pdev
+ * @val: val
+ *
+ * Return: return QDF_STATUS
+ */
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+static inline
+QDF_STATUS dp_monitor_config_undecoded_metadata_capture(struct dp_pdev *pdev,
+							int val)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = pdev->soc->monitor_soc;
+
+	if (!mon_soc)
+		return QDF_STATUS_E_FAILURE;
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops ||
+	    !monitor_ops->mon_config_undecoded_metadata_capture) {
+		dp_mon_debug("callback not registered");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return monitor_ops->mon_config_undecoded_metadata_capture(pdev, val);
+}
+#else
+static inline
+QDF_STATUS dp_monitor_config_undecoded_metadata_capture(struct dp_pdev *pdev,
+							int val)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 /*
  * dp_monitor_htt_srng_setup() - Setup htt srng
  * @soc: point to soc

+ 62 - 0
dp/wifi3.0/monitor/dp_mon_filter.c

@@ -89,8 +89,47 @@ void dp_mon_filter_show_filter(struct dp_mon_pdev *mon_pdev,
 	DP_MON_FILTER_PRINT("md_data_filter: 0x%x", tlv_filter->md_data_filter);
 	DP_MON_FILTER_PRINT("md_mgmt_filter: 0x%x", tlv_filter->md_mgmt_filter);
 	DP_MON_FILTER_PRINT("md_ctrl_filter: 0x%x", tlv_filter->md_ctrl_filter);
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	DP_MON_FILTER_PRINT("fp_phy_err: %d", tlv_filter->fp_phy_err);
+	DP_MON_FILTER_PRINT("fp_phy_err_buf_src: %d",
+			    tlv_filter->fp_phy_err_buf_src);
+	DP_MON_FILTER_PRINT("fp_phy_err_buf_dest: %d",
+			    tlv_filter->fp_phy_err_buf_dest);
+	DP_MON_FILTER_PRINT("phy_err_mask: 0x%x", tlv_filter->phy_err_mask);
+	DP_MON_FILTER_PRINT("phy_err_mask_cont: 0x%x",
+			    tlv_filter->phy_err_mask_cont);
+#endif
 }
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+static inline void
+dp_mon_set_fp_phy_err_filter(struct htt_rx_ring_tlv_filter *tlv_filter,
+			     struct dp_mon_filter *mon_filter,
+			     int32_t current_mode)
+{
+	if (current_mode == DP_MON_FILTER_UNDECODED_METADATA_CAPTURE_MODE) {
+		tlv_filter->fp_phy_err =
+			mon_filter->tlv_filter.fp_phy_err;
+		tlv_filter->fp_phy_err_buf_src =
+			mon_filter->tlv_filter.fp_phy_err_buf_src;
+		tlv_filter->fp_phy_err_buf_dest =
+			mon_filter->tlv_filter.fp_phy_err_buf_dest;
+		tlv_filter->phy_err_mask =
+			mon_filter->tlv_filter.phy_err_mask;
+		tlv_filter->phy_err_mask_cont =
+			mon_filter->tlv_filter.phy_err_mask_cont;
+		tlv_filter->phy_err_filter_valid =
+			mon_filter->tlv_filter.phy_err_filter_valid;
+	}
+}
+#else
+static inline void
+dp_mon_set_fp_phy_err_filter(struct htt_rx_ring_tlv_filter *tlv_filter,
+			     struct dp_mon_filter *mon_filter,
+			     int32_t current_mode)
+{
+}
+#endif
 /**
  * dp_mon_filter_h2t_setup() - Setup the filter for the Target setup
  * @soc: DP soc handle
@@ -216,6 +255,9 @@ void dp_mon_filter_h2t_setup(struct dp_soc *soc, struct dp_pdev *pdev,
 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_CTRL);
 		dst_filter |= src_filter;
 		DP_MON_FILTER_SET(tlv_filter, FILTER_MD_CTRL, dst_filter);
+
+		dp_mon_set_fp_phy_err_filter(tlv_filter, mon_filter,
+					     current_mode);
 	}
 
 	dp_mon_filter_show_filter(mon_pdev, 0, filter);
@@ -330,6 +372,26 @@ void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev)
 }
 #endif /* QCA_ENHANCED_STATS_SUPPORT */
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+void dp_mon_filter_setup_undecoded_metadata_mode(struct dp_pdev *pdev)
+{
+	struct dp_mon_ops *mon_ops = NULL;
+
+	mon_ops = dp_mon_ops_get(pdev->soc);
+	if (mon_ops && mon_ops->mon_filter_setup_undecoded_metadata_capture)
+		mon_ops->mon_filter_setup_undecoded_metadata_capture(pdev);
+}
+
+void dp_mon_filter_reset_undecoded_metadata_mode(struct dp_pdev *pdev)
+{
+	struct dp_mon_ops *mon_ops = NULL;
+
+	mon_ops = dp_mon_ops_get(pdev->soc);
+	if (mon_ops && mon_ops->mon_filter_reset_undecoded_metadata_capture)
+		mon_ops->mon_filter_reset_undecoded_metadata_capture(pdev);
+}
+#endif /* QCA_UNDECODED_METADATA_SUPPORT */
+
 #ifdef QCA_MCOPY_SUPPORT
 void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev)
 {

+ 52 - 0
dp/wifi3.0/monitor/dp_mon_filter.h

@@ -107,6 +107,7 @@ struct dp_mon_filter {
  * @DP_MON_FILTER_PKT_LOG_LITE_MODE: Packet log lite mode
  * @DP_MON_FILTER_PKT_LOG_CBF_MODE: Packet log cbf mode
  * @DP_MON_FILTER_PKT_LOG_HYBRID_MODE: Packet log hybrid mode
+ * @DP_MON_FILTER_RX_UNDECODED_METADATA_CAPTURE_MODE: Undecoded frame capture
  */
 enum dp_mon_filter_mode {
 #ifdef QCA_ENHANCED_STATS_SUPPORT
@@ -131,6 +132,9 @@ enum dp_mon_filter_mode {
 	DP_MON_FILTER_PKT_LOG_HYBRID_MODE,
 #endif
 #endif /* WDI_EVENT_ENABLE */
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	DP_MON_FILTER_UNDECODED_METADATA_CAPTURE_MODE,
+#endif
 	DP_MON_FILTER_MAX_MODE
 };
 
@@ -164,6 +168,38 @@ enum dp_mon_filter_action {
 	DP_MON_FILTER_SET,
 };
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+/**
+ * enum dp_mon_fp_phy_err_buf_source - fp_phy_err_buf_src indicates the source
+ * ring selection for the FP PHY ERR status tlv.
+ * @WBM2RXDMA_BUF_SOURCE_RING: 0 - wbm2rxdma_buf_source_ring
+ * @FW2RXDMA_BUF_SOURCE_RING: 1 - fw2rxdma_buf_source_ring
+ * @SW2RXDMA_BUF_SOURCE_RING: 2 - sw2rxdma_buf_source_ring
+ * @NO_BUFFER_RING: 3 - no_buffer_ring
+ */
+enum dp_mon_fp_phy_err_buf_source {
+	WBM2RXDMA_BUF_SOURCE_RING,
+	FW2RXDMA_BUF_SOURCE_RING,
+	SW2RXDMA_BUF_SOURCE_RING,
+	NO_BUFFER_RING
+};
+
+/**
+ * enum dp_mon_fp_phy_err_buf_dest - fp_phy_err_buf_dest indicates the
+ * destination ring selection for the FP PHY ERR status tlv.
+ * @RXDMA_RELEASING_RING: 0 - rxdma_release_ring
+ * @RXDMA2FW_RING: 1 - rxdma2fw_ring
+ * @RXDMA2SW_RING: 2 - rxdma2sw_ring
+ * @RXDMA2REO_RING: 3 - rxdma2reo_ring
+ */
+enum dp_mon_fp_phy_err_buf_dest {
+	RXDMA_RELEASING_RING,
+	RXDMA2FW_RING,
+	RXDMA2SW_RING,
+	RXDMA2REO_RING
+};
+#endif
+
 /**
  * dp_mon_filters_reset() - reset all filters
  * @pdev: DP pdev handle
@@ -198,6 +234,22 @@ void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev);
 void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev);
 #endif /* QCA_MCOPY_SUPPORT */
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+/**
+ * dp_mon_filter_setup_undecoded_metadata_mode() - Setup the undecoded
+ *  metadata capture mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_undecoded_metadata_mode(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_reset_undecoded_metadata_mode() - Reset the undecoded
+ * metadata capture mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_undecoded_metadata_mode(struct dp_pdev *pdev);
+#endif /* QCA_UNDECODED_METADATA_SUPPORT */
+
 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
 /**
  * dp_mon_filter_setup_smart_monitor() - Setup the smart monitor mode filter

+ 177 - 0
dp/wifi3.0/monitor/dp_rx_mon.c

@@ -1073,6 +1073,183 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev,
 }
 #endif/* QCA_ENHANCED_STATS_SUPPORT */
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+/**
+ * dp_rx_populate_cdp_indication_ppdu_undecoded_metadata() - Populate cdp
+ * rx indication structure
+ * @pdev: pdev ctx
+ * @ppdu_info: ppdu info structure from ppdu ring
+ * @cdp_rx_ppdu: Rx PPDU indication structure
+ *
+ * Return: none
+ */
+static void
+dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(struct dp_pdev *pdev,
+				struct hal_rx_ppdu_info *ppdu_info,
+				struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
+{
+	uint32_t chain;
+
+	cdp_rx_ppdu->phyrx_abort = ppdu_info->rx_status.phyrx_abort;
+	cdp_rx_ppdu->phyrx_abort_reason =
+		ppdu_info->rx_status.phyrx_abort_reason;
+
+	cdp_rx_ppdu->first_data_seq_ctrl =
+		ppdu_info->rx_status.first_data_seq_ctrl;
+	cdp_rx_ppdu->frame_ctrl =
+		ppdu_info->rx_status.frame_control;
+	cdp_rx_ppdu->tcp_msdu_count = ppdu_info->rx_status.tcp_msdu_count;
+	cdp_rx_ppdu->udp_msdu_count = ppdu_info->rx_status.udp_msdu_count;
+	cdp_rx_ppdu->other_msdu_count = ppdu_info->rx_status.other_msdu_count;
+	cdp_rx_ppdu->u.preamble = ppdu_info->rx_status.preamble_type;
+	cdp_rx_ppdu->num_mpdu = ppdu_info->com_info.mpdu_cnt_fcs_ok;
+	cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count +
+				 cdp_rx_ppdu->udp_msdu_count +
+				 cdp_rx_ppdu->other_msdu_count);
+
+	cdp_rx_ppdu->retries = CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl) ?
+		ppdu_info->com_info.mpdu_cnt_fcs_ok : 0;
+
+	if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1)
+		cdp_rx_ppdu->is_ampdu = 1;
+	else
+		cdp_rx_ppdu->is_ampdu = 0;
+	cdp_rx_ppdu->tid = ppdu_info->rx_status.tid;
+
+	cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id;
+	cdp_rx_ppdu->length = ppdu_info->rx_status.ppdu_len;
+	cdp_rx_ppdu->duration = ppdu_info->rx_status.duration;
+	cdp_rx_ppdu->u.bw = ppdu_info->rx_status.bw;
+	cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss;
+	cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs;
+	if (ppdu_info->rx_status.sgi == VHT_SGI_NYSM &&
+	    ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)
+		cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US;
+	else
+		cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi;
+
+	cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc;
+	cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type;
+	cdp_rx_ppdu->u.ltf_size = (ppdu_info->rx_status.he_data5 >>
+				   QDF_MON_STATUS_HE_LTF_SIZE_SHIFT) & 0x3;
+
+	cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb;
+	cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft;
+	cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_num;
+	cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed;
+	cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len;
+	cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate;
+	cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size;
+
+	if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) {
+		cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc;
+		cdp_rx_ppdu->vht_no_txop_ps =
+			ppdu_info->rx_status.vht_no_txop_ps;
+		cdp_rx_ppdu->vht_crc = ppdu_info->rx_status.vht_crc;
+		cdp_rx_ppdu->group_id = ppdu_info->rx_status.vht_flag_values5;
+	} else if (ppdu_info->rx_status.preamble_type ==
+			HAL_RX_PKT_TYPE_11AX) {
+		cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >>
+				       QDF_MON_STATUS_STBC_SHIFT) & 0x1;
+		cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >>
+				      QDF_MON_STATUS_DCM_SHIFT) & 0x1;
+	} else {
+		cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.ht_stbc;
+		cdp_rx_ppdu->ht_length = ppdu_info->rx_status.ht_length;
+		cdp_rx_ppdu->ht_smoothing = ppdu_info->rx_status.smoothing;
+		cdp_rx_ppdu->ht_not_sounding =
+			ppdu_info->rx_status.not_sounding;
+		cdp_rx_ppdu->ht_aggregation = ppdu_info->rx_status.aggregation;
+		cdp_rx_ppdu->ht_stbc = ppdu_info->rx_status.ht_stbc;
+		cdp_rx_ppdu->ht_crc = ppdu_info->rx_status.ht_crc;
+	}
+
+	cdp_rx_ppdu->l_sig_length = ppdu_info->rx_status.l_sig_length;
+	cdp_rx_ppdu->l_sig_a_parity = ppdu_info->rx_status.l_sig_a_parity;
+	cdp_rx_ppdu->l_sig_a_pkt_type = ppdu_info->rx_status.l_sig_a_pkt_type;
+
+	if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AX) {
+		cdp_rx_ppdu->he_crc = ppdu_info->rx_status.he_crc;
+		cdp_rx_ppdu->bss_color_id =
+			ppdu_info->rx_status.he_data3 & 0x3F;
+		cdp_rx_ppdu->beam_change = (ppdu_info->rx_status.he_data3 >>
+				QDF_MON_STATUS_BEAM_CHANGE_SHIFT) & 0x1;
+		cdp_rx_ppdu->dl_ul_flag = (ppdu_info->rx_status.he_data3 >>
+		QDF_MON_STATUS_DL_UL_SHIFT) & 0x1;
+		cdp_rx_ppdu->ldpc_extra_sym = (ppdu_info->rx_status.he_data3 >>
+				QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT) & 0x1;
+		cdp_rx_ppdu->special_reuse =
+			ppdu_info->rx_status.he_data4 & 0xF;
+		cdp_rx_ppdu->ltf_sym = (ppdu_info->rx_status.he_data5 >>
+				QDF_MON_STATUS_HE_LTF_SYM_SHIFT) & 0x7;
+		cdp_rx_ppdu->txbf = (ppdu_info->rx_status.he_data5 >>
+				QDF_MON_STATUS_TXBF_SHIFT) & 0x1;
+		cdp_rx_ppdu->pe_disambiguity = (ppdu_info->rx_status.he_data5 >>
+				QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT) & 0x1;
+		cdp_rx_ppdu->pre_fec_pad = (ppdu_info->rx_status.he_data5 >>
+				QDF_MON_STATUS_PRE_FEC_PAD_SHIFT) & 0x3;
+		cdp_rx_ppdu->dopplar = (ppdu_info->rx_status.he_data6 >>
+				QDF_MON_STATUS_DOPPLER_SHIFT) & 0x1;
+		cdp_rx_ppdu->txop_duration = (ppdu_info->rx_status.he_data6 >>
+				QDF_MON_STATUS_TXOP_SHIFT) & 0x7F;
+		cdp_rx_ppdu->sig_b_mcs = ppdu_info->rx_status.he_flags1 & 0x7;
+		cdp_rx_ppdu->sig_b_dcm = (ppdu_info->rx_status.he_flags1 >>
+				QDF_MON_STATUS_DCM_FLAG_1_SHIFT) & 0x1;
+		cdp_rx_ppdu->sig_b_sym = (ppdu_info->rx_status.he_flags2 >>
+				QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT) & 0xF;
+		cdp_rx_ppdu->sig_b_comp = (ppdu_info->rx_status.he_flags2 >>
+			QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT) & 0x1;
+	}
+	dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu);
+	dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu);
+	cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna;
+
+	cdp_rx_ppdu->nf = ppdu_info->rx_status.chan_noise_floor;
+	for (chain = 0; chain < MAX_CHAIN; chain++)
+		cdp_rx_ppdu->per_chain_rssi[chain] =
+			ppdu_info->rx_status.rssi[chain];
+
+	cdp_rx_ppdu->is_mcast_bcast = ppdu_info->nac_info.mcast_bcast;
+
+	cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users;
+
+	dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu);
+}
+
+void
+dp_rx_handle_ppdu_undecoded_metadata(struct dp_soc *soc, struct dp_pdev *pdev,
+				     struct hal_rx_ppdu_info *ppdu_info)
+{
+	qdf_nbuf_t ppdu_nbuf;
+	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
+
+	 /* Return if RX_ABORT not set */
+	if (ppdu_info->rx_status.phyrx_abort == 0)
+		return;
+
+	ppdu_nbuf = qdf_nbuf_alloc(soc->osdev,
+				   sizeof(struct cdp_rx_indication_ppdu),
+				   0, 0, FALSE);
+	if (ppdu_nbuf) {
+		cdp_rx_ppdu = ((struct cdp_rx_indication_ppdu *)
+				qdf_nbuf_data(ppdu_nbuf));
+
+		qdf_mem_zero(cdp_rx_ppdu,
+			     sizeof(struct cdp_rx_indication_ppdu));
+		dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(pdev,
+				ppdu_info, cdp_rx_ppdu);
+
+		if (!qdf_nbuf_put_tail(ppdu_nbuf,
+				       sizeof(struct cdp_rx_indication_ppdu)))
+			return;
+
+		dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC_UNDECODED_METADATA,
+				     soc, ppdu_nbuf, HTT_INVALID_PEER,
+				     WDI_NO_VAL, pdev->pdev_id);
+	}
+}
+#endif/* QCA_UNDECODED_METADATA_SUPPORT */
+
 #ifdef QCA_MCOPY_SUPPORT
 QDF_STATUS
 dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,

+ 23 - 0
dp/wifi3.0/monitor/dp_rx_mon.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 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
@@ -335,6 +336,28 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev,
 }
 #endif /* QCA_ENHANCED_STATS_SUPPORT */
 
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+/**
+ * dp_rx_handle_ppdu_undecoded_metadata() - Allocate and deliver ppdu info
+ * undecoded metadata to cdp layer
+ * @soc: core txrx main context
+ * @pdev: pdev strcuture
+ * @ppdu_info: structure for rx ppdu ring
+ *
+ * Return: none
+ */
+void
+dp_rx_handle_ppdu_undecoded_metadata(struct dp_soc *soc, struct dp_pdev *pdev,
+				     struct hal_rx_ppdu_info *ppdu_info);
+
+#else
+static inline void
+dp_rx_handle_ppdu_undecoded_metadata(struct dp_soc *soc, struct dp_pdev *pdev,
+				     struct hal_rx_ppdu_info *ppdu_info)
+{
+}
+#endif /* QCA_UNDECODED_METADATA_SUPPORT */
+
 #ifdef QCA_MCOPY_SUPPORT
 /**
  * dp_rx_handle_mcopy_mode() - Allocate and deliver first MSDU payload

+ 32 - 0
qdf/inc/qdf_nbuf.h

@@ -332,6 +332,21 @@ typedef __qdf_nbuf_queue_t qdf_nbuf_queue_t;
  * @eht_known: EHT property of received frame
  * @eht_data: EHT property of received frame
  * @eht_user_info: EHT USER property of received frame
+ * @phyrx_abort: phy aborted undecoded frame indication
+ * @phyrx_abort_reason: abort reason in phyrx_abort_request_info
+ * @vht_crc: vht crc
+ * @vht_no_txop_ps: TXOP power save mode
+ * @he_crc: he crc
+ * @l_sig_length: L SIG A length
+ * @l_sig_a_parity: L SIG A parity
+ * @l_sig_a_pkt_type: L SIG A info pkt type
+ * @l_sig_a_implicit_sounding: L SIG A info captured implicit sounding
+ * @ht_length: num of bytes in PSDU
+ * @smoothing: Indicate smoothing
+ * @not_sounding: Indicate sounding
+ * @aggregation: Indicate A-MPDU format
+ * @ht_stbc: Indicate stbc
+ * @ht_crc: ht crc
  */
 struct mon_rx_status {
 	uint64_t tsft;
@@ -433,6 +448,23 @@ struct mon_rx_status {
 	uint32_t eht_known;
 	uint32_t eht_data[6];
 	uint32_t eht_user_info[4];
+#ifdef QCA_UNDECODED_METADATA_SUPPORT
+	uint32_t phyrx_abort:1,
+		 phyrx_abort_reason:8,
+		 vht_crc:8,
+		 vht_no_txop_ps:1,
+		 he_crc:4;
+	uint32_t l_sig_length:12,
+		l_sig_a_parity:1,
+		l_sig_a_pkt_type:4,
+		l_sig_a_implicit_sounding:1;
+	uint32_t ht_length:16,
+		smoothing:1,
+		not_sounding:1,
+		aggregation:1,
+		ht_stbc:2,
+		ht_crc:8;
+#endif
 };
 
 /**