Merge "qca-wifi: After NOL timeout add channels to ETSI PreCAC Required List"
diff --git a/dp/inc/cdp_txrx_extd_struct.h b/dp/inc/cdp_txrx_extd_struct.h
new file mode 100644
index 0000000..c05b901
--- /dev/null
+++ b/dp/inc/cdp_txrx_extd_struct.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016-2019 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef _CDP_TXRX_EXTD_STRUCT_H_
+#define _CDP_TXRX_EXTD_STRUCT_H_
+
+/* Maximum number of receive chains */
+#define CDP_MAX_RX_CHAINS 8
+
+#ifdef WLAN_RX_PKT_CAPTURE_ENH
+/**
+ * struct cdp_rx_indication_mpdu_info - Rx MPDU info
+ * @ppdu_id: PPDU Id
+ * @duration: PPDU duration
+ * @first_data_seq_ctrl: Sequence control field of first data frame
+ * @ltf_size: ltf_size
+ * @stbc: When set, STBC rate was used
+ * @he_re: he_re (range extension)
+ * @bw: Bandwidth
+ *       <enum 0 bw_20_MHz>
+ *       <enum 1 bw_40_MHz>
+ *       <enum 2 bw_80_MHz>
+ *       <enum 3 bw_160_MHz>
+ * @nss: NSS 1,2, ...8
+ * @mcs: MCS index
+ * @preamble: preamble
+ * @gi: <enum 0     0_8_us_sgi > Legacy normal GI
+ *       <enum 1     0_4_us_sgi > Legacy short GI
+ *       <enum 2     1_6_us_sgi > HE related GI
+ *       <enum 3     3_2_us_sgi > HE
+ * @dcm: dcm
+ * @ldpc: ldpc
+ * @fcs_err: FCS error
+ * @ppdu_type: SU/MU_MIMO/MU_OFDMA/MU_MIMO_OFDMA/UL_TRIG/BURST_BCN/UL_BSR_RESP/
+ * UL_BSR_TRIG/UNKNOWN
+ * @rssi_comb: Combined RSSI value (units = dB above noise floor)
+ * @nf: noise floor
+ * @timestamp: TSF at the reception of PPDU
+ * @length: PPDU length
+ * @per_chain_rssi: RSSI per chain
+ * @channel: Channel informartion
+ */
+struct cdp_rx_indication_mpdu_info {
+	uint32_t ppdu_id;
+	uint16_t duration;
+	uint16_t first_data_seq_ctrl;
+	uint64_t ltf_size:2,
+		 stbc:1,
+		 he_re:1,
+		 bw:4,
+		 ofdma_info_valid:1,
+		 ofdma_ru_start_index:7,
+		 ofdma_ru_width:7,
+		 nss:4,
+		 mcs:4,
+		 preamble:4,
+		 gi:4,
+		 dcm:1,
+		 ldpc:1,
+		 fcs_err:1,
+		 ppdu_type:5;
+	uint32_t rssi_comb;
+	uint32_t nf;
+	uint64_t timestamp;
+	uint32_t length;
+	uint8_t per_chain_rssi[MAX_CHAIN];
+	uint8_t channel;
+};
+
+/**
+ * struct cdp_rx_indication_mpdu- Rx MPDU plus MPDU info
+ * @mpdu_info: defined in cdp_rx_indication_mpdu_info
+ * @data: skb chain of a MPDU. The first of 128 Byte of MPDU
+ *        chained with first of 128 Byte of MSDUs.
+ */
+struct cdp_rx_indication_mpdu {
+	struct cdp_rx_indication_mpdu_info mpdu_info;
+	qdf_nbuf_t nbuf;
+};
+#endif /* WLAN_RX_PKT_CAPTURE_ENH */
+#endif /* _CDP_TXRX_EXTD_STRUCT_H_ */
diff --git a/dp/wifi3.0/dp_rx_mon_feature.c b/dp/wifi3.0/dp_rx_mon_feature.c
new file mode 100644
index 0000000..2982f83
--- /dev/null
+++ b/dp/wifi3.0/dp_rx_mon_feature.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2017-2019 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "hal_hw_headers.h"
+#include "dp_types.h"
+#include "dp_rx.h"
+#include "dp_peer.h"
+#include "hal_rx.h"
+#include "hal_api.h"
+#include "qdf_trace.h"
+#include "qdf_nbuf.h"
+#include "hal_api_mon.h"
+#include "dp_rx_mon.h"
+#include "dp_internal.h"
+#include "qdf_mem.h"   /* qdf_mem_malloc,free */
+
+#ifdef WLAN_RX_PKT_CAPTURE_ENH
+static inline void
+dp_rx_free_msdu_list(struct msdu_list *msdu_list)
+{
+	qdf_nbuf_list_free(msdu_list->head);
+	msdu_list->head = NULL;
+	msdu_list->tail = NULL;
+	msdu_list->sum_len = 0;
+}
+
+/**
+ * dp_nbuf_set_data_and_len() - set nbuf data and len
+ * @buf: Network buf instance
+ * @data: pointer to nbuf data
+ * @len: nbuf data length
+ *
+ * Return: none
+ */
+static inline void dp_nbuf_set_data_and_len(qdf_nbuf_t buf, unsigned char *data
+					    , int len)
+{
+	qdf_nbuf_set_data_pointer(buf, data);
+	qdf_nbuf_set_len(buf, len);
+	qdf_nbuf_set_tail_pointer(buf, len);
+}
+
+/*
+ * dp_rx_populate_cdp_indication_mpdu_info() - Populate cdp rx indication
+ * MPDU info structure
+ * @pdev: pdev ctx
+ * @ppdu_info: ppdu info structure from monitor status ring
+ * @cdp_mpdu_info: cdp rx indication MPDU info structure
+ * @user: user ID
+ *
+ * Return: none
+ */
+void
+dp_rx_populate_cdp_indication_mpdu_info(
+	struct dp_pdev *pdev,
+	struct hal_rx_ppdu_info *ppdu_info,
+	struct cdp_rx_indication_mpdu_info *cdp_mpdu_info,
+	uint32_t user)
+{
+	int i;
+
+	cdp_mpdu_info->ppdu_id = ppdu_info->com_info.ppdu_id;
+	cdp_mpdu_info->duration = ppdu_info->rx_status.duration;
+	cdp_mpdu_info->bw = ppdu_info->rx_status.bw;
+	if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) &&
+	    (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC))
+		cdp_mpdu_info->gi = CDP_SGI_0_4_US;
+	else
+		cdp_mpdu_info->gi = ppdu_info->rx_status.sgi;
+	cdp_mpdu_info->ldpc = ppdu_info->rx_status.ldpc;
+	cdp_mpdu_info->preamble = ppdu_info->rx_status.preamble_type;
+	cdp_mpdu_info->ppdu_type = ppdu_info->rx_status.reception_type;
+	cdp_mpdu_info->rssi_comb = ppdu_info->rx_status.rssi_comb;
+	cdp_mpdu_info->timestamp = ppdu_info->rx_status.tsft;
+
+	cdp_mpdu_info->nss = ppdu_info->rx_user_status[user].nss;
+	cdp_mpdu_info->mcs = ppdu_info->rx_user_status[user].mcs;
+	for (i = 0; i < MAX_CHAIN; i++)
+		cdp_mpdu_info->per_chain_rssi[i] = ppdu_info->rx_status.rssi[i];
+}
+
+/*
+ * dp_rx_handle_enh_capture() - Deliver Rx enhanced capture data
+ * @pdev: pdev ctx
+ * @ppdu_info: ppdu info structure from monitor status ring
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+dp_rx_handle_enh_capture(struct dp_soc *soc, struct dp_pdev *pdev,
+			 struct hal_rx_ppdu_info *ppdu_info)
+{
+	qdf_nbuf_t  nbuf;
+	uint32_t user;
+	qdf_nbuf_queue_t *mpdu_q;
+	struct cdp_rx_indication_mpdu *mpdu_ind;
+	struct cdp_rx_indication_mpdu_info *mpdu_info;
+	struct msdu_list *msdu_list;
+
+	user = 0;
+	mpdu_q = &pdev->mpdu_q[user];
+
+	while (!qdf_nbuf_is_queue_empty(mpdu_q)) {
+		msdu_list = &pdev->msdu_list[user];
+		dp_rx_free_msdu_list(msdu_list);
+		mpdu_ind = &pdev->mpdu_ind[user];
+		mpdu_info = &mpdu_ind->mpdu_info;
+
+		dp_rx_populate_cdp_indication_mpdu_info(
+			pdev, &pdev->ppdu_info, mpdu_info, user);
+
+		while (!qdf_nbuf_is_queue_empty(mpdu_q)) {
+			nbuf = qdf_nbuf_queue_remove(mpdu_q);
+			mpdu_ind->nbuf = nbuf;
+			mpdu_info->fcs_err = QDF_NBUF_CB_RX_FCS_ERR(nbuf);
+			dp_wdi_event_handler(WDI_EVENT_RX_MPDU,
+					     soc, mpdu_ind, HTT_INVALID_PEER,
+					     WDI_NO_VAL, pdev->pdev_id);
+		}
+		user++;
+		mpdu_q = &pdev->mpdu_q[user];
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * dp_rx_mon_enh_capture_process() - Rx enhanced capture mode
+ *	processing.
+ * @pdev: pdev structure
+ * @tlv_status: processed TLV status
+ * @status_nbuf: monitor status ring buffer
+ * @ppdu_info: ppdu info structure from monitor status ring
+ * @nbuf_used: nbuf need a clone
+ * @rx_enh_capture_mode: Rx enhanced capture mode
+ *
+ * Return: none
+ */
+void
+dp_rx_mon_enh_capture_process(struct dp_pdev *pdev, uint32_t tlv_status,
+			      qdf_nbuf_t status_nbuf,
+			      struct hal_rx_ppdu_info *ppdu_info,
+			      bool *nbuf_used,
+			      uint32_t rx_enh_capture_mode)
+{
+	qdf_nbuf_t nbuf;
+	struct msdu_list *msdu_list;
+	uint32_t user_id;
+
+	if (rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_DISABLED)
+		return;
+
+	user_id = ppdu_info->user_id;
+
+	if ((tlv_status == HAL_TLV_STATUS_HEADER) && (
+	    (rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU_MSDU) ||
+	    ((rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) &&
+	    pdev->is_mpdu_hdr[user_id]))) {
+		if (*nbuf_used) {
+			nbuf = qdf_nbuf_clone(status_nbuf);
+		} else {
+			*nbuf_used = true;
+			nbuf = status_nbuf;
+		}
+
+		dp_nbuf_set_data_and_len(nbuf, ppdu_info->data,
+					  ppdu_info->hdr_len);
+
+		if (pdev->is_mpdu_hdr[user_id]) {
+			qdf_nbuf_queue_add(&pdev->mpdu_q[user_id],
+					   nbuf);
+			pdev->is_mpdu_hdr[user_id] = false;
+		} else {
+			msdu_list = &pdev->msdu_list[user_id];
+			if (!msdu_list->head)
+				msdu_list->head = nbuf;
+			else
+				msdu_list->tail->next = nbuf;
+			msdu_list->tail = nbuf;
+			msdu_list->sum_len += qdf_nbuf_len(nbuf);
+		}
+	}
+
+	if (tlv_status == HAL_TLV_STATUS_MPDU_END) {
+		msdu_list = &pdev->msdu_list[user_id];
+		nbuf = qdf_nbuf_queue_last(&pdev->mpdu_q[user_id]);
+
+		if (nbuf) {
+			qdf_nbuf_append_ext_list(nbuf,
+						 msdu_list->head,
+						 msdu_list->sum_len);
+			msdu_list->head = NULL;
+			msdu_list->tail = NULL;
+			msdu_list->sum_len = 0;
+			QDF_NBUF_CB_RX_FCS_ERR(nbuf) =  ppdu_info->fcs_err;
+			pdev->is_mpdu_hdr[user_id] = true;
+		} else {
+			dp_rx_free_msdu_list(msdu_list);
+		}
+	}
+}
+
+/*
+ * dp_config_enh_rx_capture()- API to enable/disable enhanced rx capture
+ * @pdev_handle: DP_PDEV handle
+ * @val: user provided value
+ *
+ * Return: 0 for success. nonzero for failure.
+ */
+QDF_STATUS
+dp_config_enh_rx_capture(struct cdp_pdev *pdev_handle, int val)
+{
+	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
+
+	if (pdev->mcopy_mode || (val < CDP_RX_ENH_CAPTURE_DISABLED) ||
+	    (val > CDP_RX_ENH_CAPTURE_MPDU_MSDU)) {
+		dp_err("Invalid mode");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (pdev->rx_enh_capture_mode)
+		dp_reset_monitor_mode(pdev_handle);
+
+	pdev->rx_enh_capture_mode = val;
+	return dp_pdev_configure_monitor_rings(pdev);
+}
+#endif
diff --git a/dp/wifi3.0/dp_rx_mon_feature.h b/dp/wifi3.0/dp_rx_mon_feature.h
new file mode 100644
index 0000000..db8bd58
--- /dev/null
+++ b/dp/wifi3.0/dp_rx_mon_feature.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017-2019 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DP_RX_MON_FEATURE_H_
+#define _DP_RX_MON_FEATURE_H_
+
+#ifdef WLAN_RX_PKT_CAPTURE_ENH
+/*
+ * dp_rx_populate_cdp_indication_mpdu_info() - Populate cdp rx indication
+ * MPDU info structure
+ * @pdev: pdev ctx
+ * @ppdu_info: ppdu info structure from monitor status ring
+ * @cdp_mpdu_info: cdp rx indication MPDU info structure
+ * @user: user ID
+ *
+ * Return: none
+ */
+void
+dp_rx_populate_cdp_indication_mpdu_info(
+	struct dp_pdev *pdev, struct hal_rx_ppdu_info *ppdu_info,
+	struct cdp_rx_indication_mpdu_info *cdp_mpdu_info,
+	uint32_t user);
+
+/*
+ * dp_rx_handle_enh_capture() - Deliver Rx enhanced capture data
+ * @pdev: pdev ctx
+ * @ppdu_info: ppdu info structure from monitor status ring
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+dp_rx_handle_enh_capture(struct dp_soc *soc, struct dp_pdev *pdev,
+			 struct hal_rx_ppdu_info *ppdu_info);
+
+/*
+ * dp_rx_mon_enh_capture_process() - Rx enhanced capture mode
+ *	processing.
+ * @pdev: pdev structure
+ * @tlv_status: processed TLV status
+ * @status_nbuf: monitor status ring buffer
+ * @ppdu_info: ppdu info structure from monitor status ring
+ * @nbuf_used: nbuf need a clone
+ * @rx_enh_capture_mode: Rx enhanced capture mode
+ *
+ * Return: none
+ */
+void
+dp_rx_mon_enh_capture_process(struct dp_pdev *pdev, uint32_t tlv_status,
+			      qdf_nbuf_t status_nbuf,
+			      struct hal_rx_ppdu_info *ppdu_info,
+			      bool *nbuf_used,
+			      uint32_t rx_enh_capture_mode);
+
+/*
+ * dp_config_enh_rx_capture()- API to enable/disable enhanced rx capture
+ * @pdev_handle: DP_PDEV handle
+ * @val: user provided value
+ *
+ * Return: 0 for success. nonzero for failure.
+ */
+QDF_STATUS
+dp_config_enh_rx_capture(struct cdp_pdev *pdev_handle, int val);
+#endif
+#endif