qcacld-3.0: Featurize monitor mode

Featurize monitor mode code.

Change-Id: I42d2d6a92d9097676ab3f8ec4a86958b8c0bc096
CRs-Fixed: 2245419
diff --git a/Kbuild b/Kbuild
index 50ee1ce..9b4de21 100644
--- a/Kbuild
+++ b/Kbuild
@@ -946,6 +946,9 @@
             $(HTT_DIR)/htt_fw_stats.o \
             $(HTT_DIR)/htt_rx.o
 
+ifeq ($(CONFIG_FEATURE_MONITOR_MODE_SUPPORT), y)
+HTT_OBJS += $(HTT_DIR)/htt_monitor_rx.o
+endif
 
 ############## INIT-DEINIT ###########
 INIT_DEINIT_DIR := init_deinit/dispatcher
@@ -1487,6 +1490,7 @@
 cppflags-$(CONFIG_CONVERGED_TDLS_ENABLE) += -DCONVERGED_TDLS_ENABLE
 cppflags-$(CONFIG_WLAN_CONV_SPECTRAL_ENABLE) += -DWLAN_CONV_SPECTRAL_ENABLE
 cppflags-$(CONFIG_WMI_CMD_STRINGS) += -DWMI_CMD_STRINGS
+cppflags-$(CONFIG_FEATURE_MONITOR_MODE_SUPPORT) += -DFEATURE_MONITOR_MODE_SUPPORT
 
 cppflags-$(CONFIG_WLAN_DISABLE_EXPORT_SYMBOL) += -DWLAN_DISABLE_EXPORT_SYMBOL
 cppflags-$(CONFIG_WIFI_POS_CONVERGED) += -DWIFI_POS_CONVERGED
diff --git a/configs/default_defconfig b/configs/default_defconfig
index 22394ac..3b23a00 100644
--- a/configs/default_defconfig
+++ b/configs/default_defconfig
@@ -507,6 +507,7 @@
 CONFIG_WLAN_CONV_SPECTRAL_ENABLE := y
 CONFIG_WLAN_SPECTRAL_ENABLE := y
 CONFIG_WMI_CMD_STRINGS := y
+CONFIG_FEATURE_MONITOR_MODE_SUPPORT := y
 
 ifeq ($(CONFIG_HELIUMPLUS), y)
 ifneq ($(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE), y)
diff --git a/configs/genoa.snoc.debug_defconfig b/configs/genoa.snoc.debug_defconfig
index 814799e..4d06e87 100644
--- a/configs/genoa.snoc.debug_defconfig
+++ b/configs/genoa.snoc.debug_defconfig
@@ -60,6 +60,7 @@
 CONFIG_CHECKSUM_OFFLOAD := y
 CONFIG_QCA_SUPPORT_TX_THROTTLE := y
 CONFIG_RX_OL := y
+CONFIG_FEATURE_MONITOR_MODE_SUPPORT := y
 
 ifeq ($(CONFIG_INET_LRO), y)
 CONFIG_WLAN_LRO := y
diff --git a/core/dp/htt/htt_internal.h b/core/dp/htt/htt_internal.h
index 1d7ee75..290ced7 100644
--- a/core/dp/htt/htt_internal.h
+++ b/core/dp/htt/htt_internal.h
@@ -896,4 +896,141 @@
 	return;
 }
 #endif
+
+#ifndef CONFIG_HL_SUPPORT
+
+#ifdef HTT_DEBUG_DATA
+#define HTT_PKT_DUMP(x) x
+#else
+#define HTT_PKT_DUMP(x) /* no-op */
+#endif
+
+#ifdef RX_HASH_DEBUG
+#define HTT_RX_CHECK_MSDU_COUNT(msdu_count) HTT_ASSERT_ALWAYS(msdu_count)
+#else
+#define HTT_RX_CHECK_MSDU_COUNT(msdu_count)     /* no-op */
+#endif
+
+#if HTT_PADDR64
+#define NEXT_FIELD_OFFSET_IN32 2
+#else /* ! HTT_PADDR64 */
+#define NEXT_FIELD_OFFSET_IN32 1
+#endif /* HTT_PADDR64 */
+
+#define RX_PADDR_MAGIC_PATTERN 0xDEAD0000
+
+#if HTT_PADDR64
+static inline qdf_dma_addr_t htt_paddr_trim_to_37(qdf_dma_addr_t paddr)
+{
+	qdf_dma_addr_t ret = paddr;
+
+	if (sizeof(paddr) > 4)
+		ret &= 0x1fffffffff;
+	return ret;
+}
+#else /* not 64 bits */
+static inline qdf_dma_addr_t htt_paddr_trim_to_37(qdf_dma_addr_t paddr)
+{
+	return paddr;
+}
+#endif /* HTT_PADDR64 */
+
+#ifdef ENABLE_DEBUG_ADDRESS_MARKING
+static inline qdf_dma_addr_t
+htt_rx_paddr_unmark_high_bits(qdf_dma_addr_t paddr)
+{
+	uint32_t markings;
+
+	if (sizeof(qdf_dma_addr_t) > 4) {
+		markings = (uint32_t)((paddr >> 16) >> 16);
+		/*
+		 * check if it is marked correctly:
+		 * See the mark_high_bits function above for the expected
+		 * pattern.
+		 * the LS 5 bits are the high bits of physical address
+		 * padded (with 0b0) to 8 bits
+		 */
+		if ((markings & 0xFFFF0000) != RX_PADDR_MAGIC_PATTERN) {
+			qdf_print("%s: paddr not marked correctly: 0x%pK!\n",
+				  __func__, (void *)paddr);
+			HTT_ASSERT_ALWAYS(0);
+		}
+
+		/* clear markings  for further use */
+		paddr = htt_paddr_trim_to_37(paddr);
+	}
+	return paddr;
+}
+
+static inline
+qdf_dma_addr_t htt_rx_in_ord_paddr_get(uint32_t *u32p)
+{
+	qdf_dma_addr_t paddr = 0;
+
+	paddr = (qdf_dma_addr_t)HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
+	if (sizeof(qdf_dma_addr_t) > 4) {
+		u32p++;
+		/* 32 bit architectures dont like <<32 */
+		paddr |= (((qdf_dma_addr_t)
+			  HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p))
+			  << 16 << 16);
+	}
+	paddr = htt_rx_paddr_unmark_high_bits(paddr);
+
+	return paddr;
+}
+#else
+#if HTT_PADDR64
+static inline
+qdf_dma_addr_t htt_rx_in_ord_paddr_get(uint32_t *u32p)
+{
+	qdf_dma_addr_t paddr = 0;
+
+	paddr = (qdf_dma_addr_t)HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
+	if (sizeof(qdf_dma_addr_t) > 4) {
+		u32p++;
+		/* 32 bit architectures dont like <<32 */
+		paddr |= (((qdf_dma_addr_t)
+			  HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p))
+			  << 16 << 16);
+	}
+	return paddr;
+}
+#else
+static inline
+qdf_dma_addr_t htt_rx_in_ord_paddr_get(uint32_t *u32p)
+{
+	return HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
+}
+#endif
+#endif /* ENABLE_DEBUG_ADDRESS_MARKING */
+
+static inline qdf_nbuf_t
+htt_rx_in_order_netbuf_pop(htt_pdev_handle pdev, qdf_dma_addr_t paddr)
+{
+	HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
+	pdev->rx_ring.fill_cnt--;
+	paddr = htt_paddr_trim_to_37(paddr);
+	return htt_rx_hash_list_lookup(pdev, paddr);
+}
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+					qdf_nbuf_t rx_ind_msg,
+					qdf_nbuf_t *head_msdu,
+					qdf_nbuf_t *tail_msdu,
+					uint32_t *replenish_cnt);
+#else
+static inline
+int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+					qdf_nbuf_t rx_ind_msg,
+					qdf_nbuf_t *head_msdu,
+					qdf_nbuf_t *tail_msdu,
+					uint32_t *replenish_cnt)
+{
+	return 0;
+}
+#endif
+#endif
+
 #endif /* _HTT_INTERNAL__H_ */
diff --git a/core/dp/htt/htt_monitor_rx.c b/core/dp/htt/htt_monitor_rx.c
new file mode 100644
index 0000000..f8cd4ec
--- /dev/null
+++ b/core/dp/htt/htt_monitor_rx.c
@@ -0,0 +1,1055 @@
+/*
+ * Copyright (c) 2011-2018 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 <qdf_mem.h>         /* qdf_mem_malloc,free, etc. */
+#include <qdf_types.h>          /* qdf_print, bool */
+#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
+#include <qdf_timer.h>		/* qdf_timer_free */
+
+#include <htt.h>                /* HTT_HL_RX_DESC_SIZE */
+#include <ol_cfg.h>
+#include <ol_rx.h>
+#include <ol_htt_rx_api.h>
+#include <htt_internal.h>       /* HTT_ASSERT, htt_pdev_t, HTT_RX_BUF_SIZE */
+#include "regtable.h"
+
+#include <cds_ieee80211_common.h>   /* ieee80211_frame, ieee80211_qoscntl */
+#include <cds_ieee80211_defines.h>  /* ieee80211_rx_status */
+#include <cds_utils.h>
+#include <wlan_policy_mgr_api.h>
+#include "ol_txrx_types.h"
+#ifdef DEBUG_DMA_DONE
+#include <asm/barrier.h>
+#include <wma_api.h>
+#endif
+#include <pktlog_ac_fmt.h>
+
+#define HTT_FCS_LEN (4)
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+enum {
+	HW_RX_DECAP_FORMAT_RAW = 0,
+	HW_RX_DECAP_FORMAT_NWIFI,
+	HW_RX_DECAP_FORMAT_8023,
+	HW_RX_DECAP_FORMAT_ETH2,
+};
+
+/**
+ * htt_rx_mon_note_capture_channel() - Make note of channel to update in
+ * radiotap
+ * @pdev: handle to htt_pdev
+ * @mon_ch: capture channel number.
+ *
+ * Return: None
+ */
+void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch)
+{
+	struct mon_channel *ch_info = &pdev->mon_ch_info;
+
+	ch_info->ch_num = mon_ch;
+	ch_info->ch_freq = cds_chan_to_freq(mon_ch);
+}
+
+#ifndef CONFIG_HL_SUPPORT
+/**
+ * htt_mon_rx_handle_amsdu_packet() - Handle consecutive fragments of amsdu
+ * @msdu: pointer to first msdu of amsdu
+ * @pdev: Handle to htt_pdev_handle
+ * @msg_word: Input and output variable, so pointer to HTT msg pointer
+ * @amsdu_len: remaining length of all N-1 msdu msdu's
+ * @frag_cnt: number of frags handled
+ *
+ * This function handles the (N-1) msdu's of amsdu, N'th msdu is already
+ * handled by calling function. N-1 msdu's are tied using frags_list.
+ * msdu_info field updated by FW indicates if this is last msdu. All the
+ * msdu's before last msdu will be of MAX payload.
+ *
+ * Return: 1 on success and 0 on failure.
+ */
+static
+int htt_mon_rx_handle_amsdu_packet(qdf_nbuf_t msdu, htt_pdev_handle pdev,
+				   uint32_t **msg_word, uint32_t amsdu_len,
+				   uint32_t *frag_cnt)
+{
+	qdf_nbuf_t frag_nbuf;
+	qdf_nbuf_t prev_frag_nbuf;
+	uint32_t len;
+	uint32_t last_frag;
+	qdf_dma_addr_t paddr;
+
+	*msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+	paddr = htt_rx_in_ord_paddr_get(*msg_word);
+	frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, paddr);
+	if (qdf_unlikely(!frag_nbuf)) {
+		qdf_print("%s: netbuf pop failed!\n", __func__);
+		return 0;
+	}
+	*frag_cnt = *frag_cnt + 1;
+	last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)*msg_word)->
+		msdu_info;
+	qdf_nbuf_append_ext_list(msdu, frag_nbuf, amsdu_len);
+	qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
+	qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
+	/* For msdu's other than parent will not have htt_host_rx_desc_base */
+	len = MIN(amsdu_len, HTT_RX_BUF_SIZE);
+	amsdu_len -= len;
+	qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
+
+	HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+					QDF_TRACE_LEVEL_INFO_HIGH,
+					qdf_nbuf_data(frag_nbuf),
+					qdf_nbuf_len(frag_nbuf)));
+	prev_frag_nbuf = frag_nbuf;
+	while (!last_frag) {
+		*msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+		paddr = htt_rx_in_ord_paddr_get(*msg_word);
+		frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, paddr);
+		last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
+			     *msg_word)->msdu_info;
+
+		if (qdf_unlikely(!frag_nbuf)) {
+			qdf_print("%s: netbuf pop failed!\n", __func__);
+			prev_frag_nbuf->next = NULL;
+			return 0;
+		}
+		*frag_cnt = *frag_cnt + 1;
+		qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
+		qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
+
+		len = MIN(amsdu_len, HTT_RX_BUF_SIZE);
+		amsdu_len -= len;
+		qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
+		HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+						QDF_TRACE_LEVEL_INFO_HIGH,
+						qdf_nbuf_data(frag_nbuf),
+						qdf_nbuf_len(frag_nbuf)));
+
+		qdf_nbuf_set_next(prev_frag_nbuf, frag_nbuf);
+		prev_frag_nbuf = frag_nbuf;
+	}
+	qdf_nbuf_set_next(prev_frag_nbuf, NULL);
+	return 1;
+}
+
+#define SHORT_PREAMBLE 1
+#define LONG_PREAMBLE  0
+#ifdef HELIUMPLUS
+/**
+ * htt_rx_get_rate() - get rate info in terms of 500Kbps from htt_rx_desc
+ * @l_sig_rate_select: OFDM or CCK rate
+ * @l_sig_rate:
+ *
+ * If l_sig_rate_select is 0:
+ * 0x8: OFDM 48 Mbps
+ * 0x9: OFDM 24 Mbps
+ * 0xA: OFDM 12 Mbps
+ * 0xB: OFDM 6 Mbps
+ * 0xC: OFDM 54 Mbps
+ * 0xD: OFDM 36 Mbps
+ * 0xE: OFDM 18 Mbps
+ * 0xF: OFDM 9 Mbps
+ * If l_sig_rate_select is 1:
+ * 0x1:  DSSS 1 Mbps long preamble
+ * 0x2:  DSSS 2 Mbps long preamble
+ * 0x3:  CCK 5.5 Mbps long preamble
+ * 0x4:  CCK 11 Mbps long preamble
+ * 0x5:  DSSS 2 Mbps short preamble
+ * 0x6:  CCK 5.5 Mbps
+ * 0x7:  CCK 11 Mbps short  preamble
+ *
+ * Return: rate interms of 500Kbps.
+ */
+static unsigned char htt_rx_get_rate(uint32_t l_sig_rate_select,
+				     uint32_t l_sig_rate, uint8_t *preamble)
+{
+	char ret = 0x0;
+	*preamble = SHORT_PREAMBLE;
+	if (l_sig_rate_select == 0) {
+		switch (l_sig_rate) {
+		case 0x8:
+			ret = 0x60;
+			break;
+		case 0x9:
+			ret = 0x30;
+			break;
+		case 0xA:
+			ret = 0x18;
+			break;
+		case 0xB:
+			ret = 0x0c;
+			break;
+		case 0xC:
+			ret = 0x6c;
+			break;
+		case 0xD:
+			ret = 0x48;
+			break;
+		case 0xE:
+			ret = 0x24;
+			break;
+		case 0xF:
+			ret = 0x12;
+			break;
+		default:
+			break;
+		}
+	} else if (l_sig_rate_select == 1) {
+		switch (l_sig_rate) {
+		case 0x1:
+			ret = 0x2;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x2:
+			ret = 0x4;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x3:
+			ret = 0xB;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x4:
+			ret = 0x16;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x5:
+			ret = 0x4;
+			break;
+		case 0x6:
+			ret = 0xB;
+			break;
+		case 0x7:
+			ret = 0x16;
+			break;
+		default:
+			break;
+		}
+	} else {
+		qdf_print("Invalid rate info\n");
+	}
+	return ret;
+}
+#else
+/**
+ * htt_rx_get_rate() - get rate info in terms of 500Kbps from htt_rx_desc
+ * @l_sig_rate_select: OFDM or CCK rate
+ * @l_sig_rate:
+ *
+ * If l_sig_rate_select is 0:
+ * 0x8: OFDM 48 Mbps
+ * 0x9: OFDM 24 Mbps
+ * 0xA: OFDM 12 Mbps
+ * 0xB: OFDM 6 Mbps
+ * 0xC: OFDM 54 Mbps
+ * 0xD: OFDM 36 Mbps
+ * 0xE: OFDM 18 Mbps
+ * 0xF: OFDM 9 Mbps
+ * If l_sig_rate_select is 1:
+ * 0x8: CCK 11 Mbps long preamble
+ *  0x9: CCK 5.5 Mbps long preamble
+ * 0xA: CCK 2 Mbps long preamble
+ * 0xB: CCK 1 Mbps long preamble
+ * 0xC: CCK 11 Mbps short preamble
+ * 0xD: CCK 5.5 Mbps short preamble
+ * 0xE: CCK 2 Mbps short preamble
+ *
+ * Return: rate interms of 500Kbps.
+ */
+static unsigned char htt_rx_get_rate(uint32_t l_sig_rate_select,
+				     uint32_t l_sig_rate, uint8_t *preamble)
+{
+	char ret = 0x0;
+	*preamble = SHORT_PREAMBLE;
+	if (l_sig_rate_select == 0) {
+		switch (l_sig_rate) {
+		case 0x8:
+			ret = 0x60;
+			break;
+		case 0x9:
+			ret = 0x30;
+			break;
+		case 0xA:
+			ret = 0x18;
+			break;
+		case 0xB:
+			ret = 0x0c;
+			break;
+		case 0xC:
+			ret = 0x6c;
+			break;
+		case 0xD:
+			ret = 0x48;
+			break;
+		case 0xE:
+			ret = 0x24;
+			break;
+		case 0xF:
+			ret = 0x12;
+			break;
+		default:
+			break;
+		}
+	} else if (l_sig_rate_select == 1) {
+		switch (l_sig_rate) {
+		case 0x8:
+			ret = 0x16;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0x9:
+			ret = 0x0B;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0xA:
+			ret = 0x4;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0xB:
+			ret = 0x02;
+			*preamble = LONG_PREAMBLE;
+			break;
+		case 0xC:
+			ret = 0x16;
+			break;
+		case 0xD:
+			ret = 0x0B;
+			break;
+		case 0xE:
+			ret = 0x04;
+			break;
+		default:
+			break;
+		}
+	} else {
+		qdf_print("Invalid rate info\n");
+	}
+	return ret;
+}
+#endif /* HELIUMPLUS */
+
+/**
+ * htt_mon_rx_get_phy_info() - Get phy info
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ * @rx_status: Return variable updated with phy_info in rx_status
+ *
+ * Return: None
+ */
+static void htt_mon_rx_get_phy_info(struct htt_host_rx_desc_base *rx_desc,
+				    struct mon_rx_status *rx_status)
+{
+	uint8_t preamble = 0;
+	uint8_t preamble_type = rx_desc->ppdu_start.preamble_type;
+	uint8_t mcs = 0, nss = 0, sgi = 0, bw = 0, beamformed = 0;
+	uint16_t vht_flags = 0, ht_flags = 0;
+	uint32_t l_sig_rate_select = rx_desc->ppdu_start.l_sig_rate_select;
+	uint32_t l_sig_rate = rx_desc->ppdu_start.l_sig_rate;
+	bool is_stbc = 0, ldpc = 0;
+
+	switch (preamble_type) {
+	case 4:
+	/* legacy */
+		rx_status->rate = htt_rx_get_rate(l_sig_rate_select, l_sig_rate,
+						&preamble);
+		break;
+	case 8:
+		is_stbc = ((VHT_SIG_A_2(rx_desc) >> 4) & 3);
+		/* fallthrough */
+	case 9:
+		ht_flags = 1;
+		sgi = (VHT_SIG_A_2(rx_desc) >> 7) & 0x01;
+		bw = (VHT_SIG_A_1(rx_desc) >> 7) & 0x01;
+		mcs = (VHT_SIG_A_1(rx_desc) & 0x7f);
+		nss = mcs >> 3;
+		beamformed =
+			(VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
+		break;
+	case 0x0c:
+		is_stbc = (VHT_SIG_A_2(rx_desc) >> 3) & 1;
+		ldpc = (VHT_SIG_A_2(rx_desc) >> 2) & 1;
+		/* fallthrough */
+	case 0x0d:
+	{
+		uint8_t gid_in_sig = ((VHT_SIG_A_1(rx_desc) >> 4) & 0x3f);
+
+		vht_flags = 1;
+		sgi = VHT_SIG_A_2(rx_desc) & 0x01;
+		bw = (VHT_SIG_A_1(rx_desc) & 0x03);
+		if (gid_in_sig == 0 || gid_in_sig == 63) {
+			/* SU case */
+			mcs = (VHT_SIG_A_2(rx_desc) >> 4) &
+				0xf;
+			nss = (VHT_SIG_A_1(rx_desc) >> 10) &
+				0x7;
+		} else {
+			/* MU case */
+			uint8_t sta_user_pos =
+				(uint8_t)((rx_desc->ppdu_start.reserved_4a >> 8)
+					  & 0x3);
+			mcs = (rx_desc->ppdu_start.vht_sig_b >> 16);
+			if (bw >= 2)
+				mcs >>= 3;
+			else if (bw > 0)
+				mcs >>= 1;
+			mcs &= 0xf;
+			nss = (((VHT_SIG_A_1(rx_desc) >> 10) +
+				sta_user_pos * 3) & 0x7);
+		}
+		beamformed = (VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
+	}
+		/* fallthrough */
+	default:
+		break;
+	}
+
+	rx_status->mcs = mcs;
+	rx_status->bw = bw;
+	rx_status->nr_ant = nss;
+	rx_status->is_stbc = is_stbc;
+	rx_status->sgi = sgi;
+	rx_status->ldpc = ldpc;
+	rx_status->beamformed = beamformed;
+	rx_status->vht_flag_values3[0] = mcs << 0x4 | (nss + 1);
+	rx_status->ht_flags = ht_flags;
+	rx_status->vht_flags = vht_flags;
+	rx_status->rtap_flags |= ((preamble == SHORT_PREAMBLE) ? BIT(1) : 0);
+	if (bw == 0)
+		rx_status->vht_flag_values2 = 0;
+	else if (bw == 1)
+		rx_status->vht_flag_values2 = 1;
+	else if (bw == 2)
+		rx_status->vht_flag_values2 = 4;
+}
+
+/**
+ * htt_mon_rx_get_rtap_flags() - Get radiotap flags
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ *
+ * Return: Bitmapped radiotap flags.
+ */
+static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc)
+{
+	uint8_t rtap_flags = 0;
+
+	/* WEP40 || WEP104 || WEP128 */
+	if (rx_desc->mpdu_start.encrypt_type == 0 ||
+	    rx_desc->mpdu_start.encrypt_type == 1 ||
+	    rx_desc->mpdu_start.encrypt_type == 3)
+		rtap_flags |= BIT(2);
+
+	/* IEEE80211_RADIOTAP_F_FRAG */
+	if (rx_desc->attention.fragment)
+		rtap_flags |= BIT(3);
+
+	/* IEEE80211_RADIOTAP_F_FCS */
+	rtap_flags |= BIT(4);
+
+	/* IEEE80211_RADIOTAP_F_BADFCS */
+	if (rx_desc->mpdu_end.fcs_err)
+		rtap_flags |= BIT(6);
+
+	return rtap_flags;
+}
+
+/**
+ * htt_rx_mon_get_rx_status() - Update information about the rx status,
+ * which is used later for radiotap updation.
+ * @rx_desc: Pointer to struct htt_host_rx_desc_base
+ * @rx_status: Return variable updated with rx_status
+ *
+ * Return: None
+ */
+static void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
+				     struct htt_host_rx_desc_base *rx_desc,
+				     struct mon_rx_status *rx_status)
+{
+	uint16_t channel_flags = 0;
+	struct mon_channel *ch_info = &pdev->mon_ch_info;
+
+	rx_status->tsft = (u_int64_t)TSF_TIMESTAMP(rx_desc);
+	rx_status->chan_freq = ch_info->ch_freq;
+	rx_status->chan_num = ch_info->ch_num;
+	htt_mon_rx_get_phy_info(rx_desc, rx_status);
+	rx_status->rtap_flags |= htt_mon_rx_get_rtap_flags(rx_desc);
+	channel_flags |= rx_desc->ppdu_start.l_sig_rate_select ?
+		IEEE80211_CHAN_CCK : IEEE80211_CHAN_OFDM;
+	channel_flags |=
+		(cds_chan_to_band(ch_info->ch_num) == CDS_BAND_2GHZ ?
+		IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
+
+	rx_status->chan_flags = channel_flags;
+	rx_status->ant_signal_db = rx_desc->ppdu_start.rssi_comb;
+}
+
+/**
+ * htt_rx_mon_amsdu_rx_in_order_pop_ll() - Monitor mode HTT Rx in order pop
+ * function
+ * @pdev: Handle to htt_pdev_handle
+ * @rx_ind_msg: In order indication message.
+ * @head_msdu: Return variable pointing to head msdu.
+ * @tail_msdu: Return variable pointing to tail msdu.
+ *
+ * This function pops the msdu based on paddr:length of inorder indication
+ * message.
+ *
+ * Return: 1 for success, 0 on failure.
+ */
+int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
+					qdf_nbuf_t rx_ind_msg,
+					qdf_nbuf_t *head_msdu,
+					qdf_nbuf_t *tail_msdu,
+					uint32_t *replenish_cnt)
+{
+	qdf_nbuf_t msdu, next, prev = NULL;
+	uint8_t *rx_ind_data;
+	uint32_t *msg_word;
+	uint32_t msdu_count;
+	struct htt_host_rx_desc_base *rx_desc;
+	struct mon_rx_status rx_status = {0};
+	uint32_t amsdu_len;
+	uint32_t len;
+	uint32_t last_frag;
+	qdf_dma_addr_t paddr;
+
+	HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
+
+	rx_ind_data = qdf_nbuf_data(rx_ind_msg);
+	msg_word = (uint32_t *)rx_ind_data;
+
+	*replenish_cnt = 0;
+	HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+					QDF_TRACE_LEVEL_INFO_HIGH,
+					(void *)rx_ind_data,
+					(int)qdf_nbuf_len(rx_ind_msg)));
+
+	/* Get the total number of MSDUs */
+	msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1));
+	HTT_RX_CHECK_MSDU_COUNT(msdu_count);
+
+	msg_word = (uint32_t *)(rx_ind_data +
+				 HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES);
+	paddr = htt_rx_in_ord_paddr_get(msg_word);
+	msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
+
+	if (qdf_unlikely(!msdu)) {
+		qdf_print("%s: netbuf pop failed!\n", __func__);
+		*tail_msdu = NULL;
+		return 0;
+	}
+	*replenish_cnt = *replenish_cnt + 1;
+
+	while (msdu_count > 0) {
+		msdu_count--;
+		/*
+		 * Set the netbuf length to be the entire buffer length
+		 * initially, so the unmap will unmap the entire buffer.
+		 */
+		qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
+		qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
+
+		/*
+		 * cache consistency has been taken care of by the
+		 * qdf_nbuf_unmap
+		 */
+		rx_desc = htt_rx_desc(msdu);
+		if ((unsigned int)(*(uint32_t *)&rx_desc->attention) &
+				RX_DESC_ATTN_MPDU_LEN_ERR_BIT) {
+			qdf_nbuf_free(msdu);
+			last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
+			     msg_word)->msdu_info;
+			while (!last_frag) {
+				msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+				paddr = htt_rx_in_ord_paddr_get(msg_word);
+				msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
+				last_frag = ((struct
+					htt_rx_in_ord_paddr_ind_msdu_t *)
+					msg_word)->msdu_info;
+				if (qdf_unlikely(!msdu)) {
+					qdf_print("%s: netbuf pop failed!\n",
+						  __func__);
+					return 0;
+				}
+				*replenish_cnt = *replenish_cnt + 1;
+				qdf_nbuf_unmap(pdev->osdev, msdu,
+					       QDF_DMA_FROM_DEVICE);
+				qdf_nbuf_free(msdu);
+			}
+			msdu = prev;
+			goto next_pop;
+		}
+
+		if (!prev)
+			(*head_msdu) = msdu;
+		prev = msdu;
+
+		HTT_PKT_DUMP(htt_print_rx_desc(rx_desc));
+		/*
+		 * Make the netbuf's data pointer point to the payload rather
+		 * than the descriptor.
+		 */
+		htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status);
+		/*
+		 * For certain platform, 350 bytes of headroom is already
+		 * appended to accommodate radiotap header but
+		 * qdf_nbuf_update_radiotap() API again will try to create
+		 * a room for radiotap header. To make our design simple
+		 * let qdf_nbuf_update_radiotap() API create a room for radiotap
+		 * header and update it, do qdf_nbuf_pull_head() operation and
+		 * pull 350 bytes of headroom.
+		 *
+		 *
+		 *
+		 *               (SKB buffer)
+		 * skb->head --> +-----------+ <-- skb->data
+		 *               |           |     (Before pulling headroom)
+		 *               |           |
+		 *               |   HEAD    |  350 bytes of headroom
+		 *               |           |
+		 *               |           |
+		 *               +-----------+ <-- skb->data
+		 *               |           |     (After pulling headroom)
+		 *               |           |
+		 *               |   DATA    |
+		 *               |           |
+		 *               |           |
+		 *               +-----------+
+		 *               |           |
+		 *               |           |
+		 *               |   TAIL    |
+		 *               |           |
+		 *               |           |
+		 *               +-----------+
+		 *
+		 */
+		if (qdf_nbuf_head(msdu) == qdf_nbuf_data(msdu))
+			qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION);
+		qdf_nbuf_update_radiotap(&rx_status, msdu,
+					 HTT_RX_STD_DESC_RESERVATION);
+		amsdu_len = HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(*(msg_word +
+						NEXT_FIELD_OFFSET_IN32));
+
+		/*
+		 * MAX_RX_PAYLOAD_SZ when we have AMSDU packet. amsdu_len in
+		 * which case is the total length of sum of all AMSDU's
+		 */
+		len = MIN(amsdu_len, MAX_RX_PAYLOAD_SZ);
+		amsdu_len -= len;
+		qdf_nbuf_trim_tail(msdu, HTT_RX_BUF_SIZE -
+				   (RX_STD_DESC_SIZE + len));
+
+		HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
+						QDF_TRACE_LEVEL_INFO_HIGH,
+						qdf_nbuf_data(msdu),
+						qdf_nbuf_len(msdu)));
+		last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
+			     msg_word)->msdu_info;
+
+		/* Handle amsdu packet */
+		if (!last_frag) {
+			/*
+			 * For AMSDU packet msdu->len is sum of all the msdu's
+			 * length, msdu->data_len is sum of length's of
+			 * remaining msdu's other than parent.
+			 */
+			if (!htt_mon_rx_handle_amsdu_packet(msdu, pdev,
+							    &msg_word,
+							    amsdu_len,
+							    replenish_cnt)) {
+				qdf_print("%s: failed to handle amsdu packet\n",
+					  __func__);
+				return 0;
+			}
+		}
+
+next_pop:
+		/* check if this is the last msdu */
+		if (msdu_count) {
+			msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
+			paddr = htt_rx_in_ord_paddr_get(msg_word);
+			next = htt_rx_in_order_netbuf_pop(pdev, paddr);
+			if (qdf_unlikely(!next)) {
+				qdf_print("%s: netbuf pop failed!\n",
+					  __func__);
+				*tail_msdu = NULL;
+				return 0;
+			}
+			*replenish_cnt = *replenish_cnt + 1;
+			if (msdu)
+				qdf_nbuf_set_next(msdu, next);
+			msdu = next;
+		} else {
+			*tail_msdu = msdu;
+			if (msdu)
+				qdf_nbuf_set_next(msdu, NULL);
+		}
+	}
+
+	return 1;
+}
+#endif /* CONFIG_HL_SUPPORT */
+
+#if !defined(QCA6290_HEADERS_DEF)
+static void
+htt_rx_parse_ppdu_start_status(struct htt_host_rx_desc_base *rx_desc,
+			       struct ieee80211_rx_status *rs)
+{
+	struct rx_ppdu_start *ppdu_start = &rx_desc->ppdu_start;
+
+	/* RSSI */
+	rs->rs_rssi = ppdu_start->rssi_comb;
+
+	/* PHY rate */
+	/*
+	 * rs_ratephy coding
+	 * [b3 - b0]
+	 * 0 -> OFDM
+	 * 1 -> CCK
+	 * 2 -> HT
+	 * 3 -> VHT
+	 * OFDM / CCK
+	 * [b7  - b4 ] => LSIG rate
+	 * [b23 - b8 ] => service field
+	 * (b'12 static/dynamic,
+	 * b'14..b'13 BW for VHT)
+	 * [b31 - b24 ] => Reserved
+	 * HT / VHT
+	 * [b15 - b4 ] => SIG A_2 12 LSBs
+	 * [b31 - b16] => SIG A_1 16 LSBs
+	 */
+	if (ppdu_start->preamble_type == 0x4) {
+		rs->rs_ratephy = ppdu_start->l_sig_rate_select;
+		rs->rs_ratephy |= ppdu_start->l_sig_rate << 4;
+		rs->rs_ratephy |= ppdu_start->service << 8;
+	} else {
+		rs->rs_ratephy = (ppdu_start->preamble_type & 0x4) ? 3 : 2;
+#ifdef HELIUMPLUS
+		rs->rs_ratephy |=
+			(ppdu_start->ht_sig_vht_sig_ah_sig_a_2 & 0xFFF) << 4;
+		rs->rs_ratephy |=
+			(ppdu_start->ht_sig_vht_sig_ah_sig_a_1 & 0xFFFF) << 16;
+#else
+		rs->rs_ratephy |= (ppdu_start->ht_sig_vht_sig_a_2 & 0xFFF) << 4;
+		rs->rs_ratephy |=
+			(ppdu_start->ht_sig_vht_sig_a_1 & 0xFFFF) << 16;
+#endif
+	}
+}
+
+/* Util fake function that has same prototype as qdf_nbuf_clone that just
+ * returns the same nbuf
+ */
+static qdf_nbuf_t htt_rx_qdf_noclone_buf(qdf_nbuf_t buf)
+{
+	return buf;
+}
+
+/* This function is used by montior mode code to restitch an MSDU list
+ * corresponding to an MPDU back into an MPDU by linking up the skbs.
+ */
+qdf_nbuf_t
+htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
+				qdf_nbuf_t head_msdu,
+				struct ieee80211_rx_status *rx_status,
+				unsigned int clone_not_reqd)
+{
+	qdf_nbuf_t msdu, mpdu_buf, prev_buf, msdu_orig, head_frag_list_cloned;
+	unsigned int decap_format, wifi_hdr_len, sec_hdr_len, msdu_llc_len,
+		 mpdu_buf_len, decap_hdr_pull_bytes, frag_list_sum_len, dir,
+		 is_amsdu, is_first_frag, amsdu_pad, msdu_len;
+	struct htt_host_rx_desc_base *rx_desc;
+	char *hdr_desc;
+	unsigned char *dest;
+	struct ieee80211_frame *wh;
+	struct ieee80211_qoscntl *qos;
+
+	/* The nbuf has been pulled just beyond the status and points to the
+	 * payload
+	 */
+	msdu_orig = head_msdu;
+	rx_desc = htt_rx_desc(msdu_orig);
+
+	/* Fill out the rx_status from the PPDU start and end fields */
+	if (rx_desc->attention.first_mpdu) {
+		htt_rx_parse_ppdu_start_status(rx_desc, rx_status);
+
+		/* The timestamp is no longer valid - It will be valid only for
+		 * the last MPDU
+		 */
+		rx_status->rs_tstamp.tsf = ~0;
+	}
+
+	decap_format =
+		GET_FIELD(&rx_desc->msdu_start, RX_MSDU_START_2_DECAP_FORMAT);
+
+	head_frag_list_cloned = NULL;
+
+	/* Easy case - The MSDU status indicates that this is a non-decapped
+	 * packet in RAW mode.
+	 * return
+	 */
+	if (decap_format == HW_RX_DECAP_FORMAT_RAW) {
+		/* Note that this path might suffer from headroom unavailabilty,
+		 * but the RX status is usually enough
+		 */
+		if (clone_not_reqd)
+			mpdu_buf = htt_rx_qdf_noclone_buf(head_msdu);
+		else
+			mpdu_buf = qdf_nbuf_clone(head_msdu);
+
+		if (!mpdu_buf)
+			goto mpdu_stitch_fail;
+
+		prev_buf = mpdu_buf;
+
+		frag_list_sum_len = 0;
+		is_first_frag = 1;
+		msdu_len = qdf_nbuf_len(mpdu_buf);
+
+		/* Drop the zero-length msdu */
+		if (!msdu_len)
+			goto mpdu_stitch_fail;
+
+		msdu_orig = qdf_nbuf_next(head_msdu);
+
+		while (msdu_orig) {
+			/* TODO: intra AMSDU padding - do we need it ??? */
+			if (clone_not_reqd)
+				msdu = htt_rx_qdf_noclone_buf(msdu_orig);
+			else
+				msdu = qdf_nbuf_clone(msdu_orig);
+
+			if (!msdu)
+				goto mpdu_stitch_fail;
+
+			if (is_first_frag) {
+				is_first_frag = 0;
+				head_frag_list_cloned = msdu;
+			}
+
+			msdu_len = qdf_nbuf_len(msdu);
+			/* Drop the zero-length msdu */
+			if (!msdu_len)
+				goto mpdu_stitch_fail;
+
+			frag_list_sum_len += msdu_len;
+
+			/* Maintain the linking of the cloned MSDUS */
+			qdf_nbuf_set_next_ext(prev_buf, msdu);
+
+			/* Move to the next */
+			prev_buf = msdu;
+			msdu_orig = qdf_nbuf_next(msdu_orig);
+		}
+
+		/* The last msdu length need be larger than HTT_FCS_LEN */
+		if (msdu_len < HTT_FCS_LEN)
+			goto mpdu_stitch_fail;
+
+		qdf_nbuf_trim_tail(prev_buf, HTT_FCS_LEN);
+
+		/* If there were more fragments to this RAW frame */
+		if (head_frag_list_cloned) {
+			qdf_nbuf_append_ext_list(mpdu_buf,
+						 head_frag_list_cloned,
+						 frag_list_sum_len);
+		}
+
+		goto mpdu_stitch_done;
+	}
+
+	/* Decap mode:
+	 * Calculate the amount of header in decapped packet to knock off based
+	 * on the decap type and the corresponding number of raw bytes to copy
+	 * status header
+	 */
+
+	hdr_desc = &rx_desc->rx_hdr_status[0];
+
+	/* Base size */
+	wifi_hdr_len = sizeof(struct ieee80211_frame);
+	wh = (struct ieee80211_frame *)hdr_desc;
+
+	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
+	if (dir == IEEE80211_FC1_DIR_DSTODS)
+		wifi_hdr_len += 6;
+
+	is_amsdu = 0;
+	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
+		qos = (struct ieee80211_qoscntl *)
+		      (hdr_desc + wifi_hdr_len);
+		wifi_hdr_len += 2;
+
+		is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU);
+	}
+
+	/* TODO: Any security headers associated with MPDU */
+	sec_hdr_len = 0;
+
+	/* MSDU related stuff LLC - AMSDU subframe header etc */
+	msdu_llc_len = is_amsdu ? (14 + 8) : 8;
+
+	mpdu_buf_len = wifi_hdr_len + sec_hdr_len + msdu_llc_len;
+
+	/* "Decap" header to remove from MSDU buffer */
+	decap_hdr_pull_bytes = 14;
+
+	/* Allocate a new nbuf for holding the 802.11 header retrieved from the
+	 * status of the now decapped first msdu. Leave enough headroom for
+	 * accomodating any radio-tap /prism like PHY header
+	 */
+#define HTT_MAX_MONITOR_HEADER (512)
+	mpdu_buf = qdf_nbuf_alloc(pdev->osdev,
+				  HTT_MAX_MONITOR_HEADER + mpdu_buf_len,
+				  HTT_MAX_MONITOR_HEADER, 4, false);
+
+	if (!mpdu_buf)
+		goto mpdu_stitch_fail;
+
+	/* Copy the MPDU related header and enc headers into the first buffer
+	 * - Note that there can be a 2 byte pad between heaader and enc header
+	 */
+
+	prev_buf = mpdu_buf;
+	dest = qdf_nbuf_put_tail(prev_buf, wifi_hdr_len);
+	if (!dest)
+		goto mpdu_stitch_fail;
+	qdf_mem_copy(dest, hdr_desc, wifi_hdr_len);
+	hdr_desc += wifi_hdr_len;
+
+	/* NOTE - This padding is present only in the RAW header status - not
+	 * when the MSDU data payload is in RAW format.
+	 */
+	/* Skip the "IV pad" */
+	if (wifi_hdr_len & 0x3)
+		hdr_desc += 2;
+
+	/* The first LLC len is copied into the MPDU buffer */
+	frag_list_sum_len = 0;
+	frag_list_sum_len -= msdu_llc_len;
+
+	msdu_orig = head_msdu;
+	is_first_frag = 1;
+	amsdu_pad = 0;
+
+	while (msdu_orig) {
+		/* TODO: intra AMSDU padding - do we need it ??? */
+		if (clone_not_reqd)
+			msdu = htt_rx_qdf_noclone_buf(msdu_orig);
+		else
+			msdu = qdf_nbuf_clone(msdu_orig);
+
+		if (!msdu)
+			goto mpdu_stitch_fail;
+
+		if (is_first_frag) {
+			is_first_frag = 0;
+			head_frag_list_cloned = msdu;
+		} else {
+			/* Maintain the linking of the cloned MSDUS */
+			qdf_nbuf_set_next_ext(prev_buf, msdu);
+
+			/* Reload the hdr ptr only on non-first MSDUs */
+			rx_desc = htt_rx_desc(msdu_orig);
+			hdr_desc = &rx_desc->rx_hdr_status[0];
+		}
+
+		/* Copy this buffers MSDU related status into the prev buffer */
+		dest = qdf_nbuf_put_tail(prev_buf, msdu_llc_len + amsdu_pad);
+		dest += amsdu_pad;
+		qdf_mem_copy(dest, hdr_desc, msdu_llc_len);
+
+		/* Push the MSDU buffer beyond the decap header */
+		qdf_nbuf_pull_head(msdu, decap_hdr_pull_bytes);
+		frag_list_sum_len +=
+			msdu_llc_len + qdf_nbuf_len(msdu) + amsdu_pad;
+
+		/*
+		 * Set up intra-AMSDU pad to be added to start of next buffer -
+		 * AMSDU pad is 4 byte pad on AMSDU subframe
+		 */
+		amsdu_pad = (msdu_llc_len + qdf_nbuf_len(msdu)) & 0x3;
+		amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
+
+		/*
+		 * TODO FIXME How do we handle MSDUs that have fraglist - Should
+		 * probably iterate all the frags cloning them along the way and
+		 * and also updating the prev_buf pointer
+		 */
+
+		/* Move to the next */
+		prev_buf = msdu;
+		msdu_orig = qdf_nbuf_next(msdu_orig);
+	}
+
+	/* TODO: Convert this to suitable qdf routines */
+	qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list_cloned,
+				 frag_list_sum_len);
+
+mpdu_stitch_done:
+	/* Check if this buffer contains the PPDU end status for TSF */
+	if (rx_desc->attention.last_mpdu)
+#ifdef HELIUMPLUS
+		rx_status->rs_tstamp.tsf =
+			rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32;
+#else
+		rx_status->rs_tstamp.tsf = rx_desc->ppdu_end.tsf_timestamp;
+#endif
+	/* All the nbufs have been linked into the ext list
+	 * and then unlink the nbuf list
+	 */
+	if (clone_not_reqd) {
+		msdu = head_msdu;
+		while (msdu) {
+			msdu_orig = msdu;
+			msdu = qdf_nbuf_next(msdu);
+			qdf_nbuf_set_next(msdu_orig, NULL);
+		}
+	}
+
+	return mpdu_buf;
+
+mpdu_stitch_fail:
+	/* Free these alloced buffers and the orig buffers in non-clone case */
+	if (!clone_not_reqd) {
+		/* Free the head buffer */
+		if (mpdu_buf)
+			qdf_nbuf_free(mpdu_buf);
+
+		/* Free the partial list */
+		while (head_frag_list_cloned) {
+			msdu = head_frag_list_cloned;
+			head_frag_list_cloned =
+				qdf_nbuf_next_ext(head_frag_list_cloned);
+			qdf_nbuf_free(msdu);
+		}
+	} else {
+		/* Free the alloced head buffer */
+		if (decap_format != HW_RX_DECAP_FORMAT_RAW)
+			if (mpdu_buf)
+				qdf_nbuf_free(mpdu_buf);
+
+		/* Free the orig buffers */
+		msdu = head_msdu;
+		while (msdu) {
+			msdu_orig = msdu;
+			msdu = qdf_nbuf_next(msdu);
+			qdf_nbuf_free(msdu_orig);
+		}
+	}
+
+	return NULL;
+}
+#endif
diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c
index 934f266..28b5793 100644
--- a/core/dp/htt/htt_rx.c
+++ b/core/dp/htt/htt_rx.c
@@ -53,12 +53,6 @@
 #endif
 #include <pktlog_ac_fmt.h>
 
-#ifdef HTT_DEBUG_DATA
-#define HTT_PKT_DUMP(x) x
-#else
-#define HTT_PKT_DUMP(x) /* no-op */
-#endif
-
 /* AR9888v1 WORKAROUND for EV#112367 */
 /* FIX THIS - remove this WAR when the bug is fixed */
 #define PEREGRINE_1_0_ZERO_LEN_PHY_ERR_WAR
@@ -111,12 +105,6 @@
 #define RX_HASH_LOG(x)          /* no-op */
 #endif
 
-#if HTT_PADDR64
-#define NEXT_FIELD_OFFSET_IN32 2
-#else /* ! HTT_PADDR64 */
-#define NEXT_FIELD_OFFSET_IN32 1
-#endif /* HTT_PADDR64 */
-
 #ifndef CONFIG_HL_SUPPORT
 /**
  * htt_get_first_packet_after_wow_wakeup() - get first packet after wow wakeup
@@ -382,36 +370,25 @@
 		HTT_WORD_GET(*(u_int32_t *)rx_desc, HTT_HL_RX_DESC_MCAST_BCAST);
 }
 
-#define RX_PADDR_MAGIC_PATTERN 0xDEAD0000
+#ifdef ENABLE_DEBUG_ADDRESS_MARKING
 static qdf_dma_addr_t
 htt_rx_paddr_mark_high_bits(qdf_dma_addr_t paddr)
 {
-#ifdef ENABLE_DEBUG_ADDRESS_MARKING
 	if (sizeof(qdf_dma_addr_t) > 4) {
 		/* clear high bits, leave lower 37 bits (paddr) */
 		paddr &= 0x01FFFFFFFFF;
 		/* mark upper 16 bits of paddr */
 		paddr |= (((uint64_t)RX_PADDR_MAGIC_PATTERN) << 32);
 	}
+	return paddr;
+}
+#else
+static qdf_dma_addr_t
+htt_rx_paddr_mark_high_bits(qdf_dma_addr_t paddr)
+{
+	return 0;
+}
 #endif
-	return paddr;
-}
-
-#if HTT_PADDR64
-static inline qdf_dma_addr_t htt_paddr_trim_to_37(qdf_dma_addr_t paddr)
-{
-	qdf_dma_addr_t ret = paddr;
-
-	if (sizeof(paddr) > 4)
-		ret &= 0x1fffffffff;
-	return ret;
-}
-#else /* not 64 bits */
-static inline qdf_dma_addr_t htt_paddr_trim_to_37(qdf_dma_addr_t paddr)
-{
-	return paddr;
-}
-#endif /* HTT_PADDR64 */
 
 #ifndef CONFIG_HL_SUPPORT
 static bool
@@ -425,76 +402,6 @@
 		 RX_MSDU_END_4_FIRST_MSDU_LSB);
 }
 
-#ifdef ENABLE_DEBUG_ADDRESS_MARKING
-static qdf_dma_addr_t
-htt_rx_paddr_unmark_high_bits(qdf_dma_addr_t paddr)
-{
-	uint32_t markings;
-
-	if (sizeof(qdf_dma_addr_t) > 4) {
-		markings = (uint32_t)((paddr >> 16) >> 16);
-		/*
-		 * check if it is marked correctly:
-		 * See the mark_high_bits function above for the expected
-		 * pattern.
-		 * the LS 5 bits are the high bits of physical address
-		 * padded (with 0b0) to 8 bits
-		 */
-		if ((markings & 0xFFFF0000) != RX_PADDR_MAGIC_PATTERN) {
-			qdf_print("%s: paddr not marked correctly: 0x%pK!\n",
-				  __func__, (void *)paddr);
-			HTT_ASSERT_ALWAYS(0);
-		}
-
-		/* clear markings  for further use */
-		paddr = htt_paddr_trim_to_37(paddr);
-	}
-	return paddr;
-}
-
-static qdf_dma_addr_t
-htt_rx_in_ord_paddr_get(uint32_t *u32p)
-{
-	qdf_dma_addr_t paddr = 0;
-
-	paddr = (qdf_dma_addr_t)HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
-	if (sizeof(qdf_dma_addr_t) > 4) {
-		u32p++;
-		/* 32 bit architectures dont like <<32 */
-		paddr |= (((qdf_dma_addr_t)
-			  HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p))
-			  << 16 << 16);
-	}
-	paddr = htt_rx_paddr_unmark_high_bits(paddr);
-
-	return paddr;
-}
-#else
-#if HTT_PADDR64
-static qdf_dma_addr_t
-htt_rx_in_ord_paddr_get(uint32_t *u32p)
-{
-	qdf_dma_addr_t paddr = 0;
-
-	paddr = (qdf_dma_addr_t)HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
-	if (sizeof(qdf_dma_addr_t) > 4) {
-		u32p++;
-		/* 32 bit architectures dont like <<32 */
-		paddr |= (((qdf_dma_addr_t)
-			  HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p))
-			  << 16 << 16);
-	}
-	return paddr;
-}
-#else
-static inline qdf_dma_addr_t
-htt_rx_in_ord_paddr_get(uint32_t *u32p)
-{
-	return HTT_RX_IN_ORD_PADDR_IND_PADDR_GET(*u32p);
-}
-
-#endif
-#endif /* ENABLE_DEBUG_ADDRESS_MARKING */
 #endif /* CONFIG_HL_SUPPORT*/
 
 /* full_reorder_offload case: this function is called with lock held */
@@ -1099,17 +1006,6 @@
 	return msdu;
 }
 
-#ifndef CONFIG_HL_SUPPORT
-static inline qdf_nbuf_t
-htt_rx_in_order_netbuf_pop(htt_pdev_handle pdev, qdf_dma_addr_t paddr)
-{
-	HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
-	pdev->rx_ring.fill_cnt--;
-	paddr = htt_paddr_trim_to_37(paddr);
-	return htt_rx_hash_list_lookup(pdev, paddr);
-}
-#endif
-
 /*
  * FIX ME: this function applies only to LL rx descs.
  * An equivalent for HL rx descs is needed.
@@ -1734,669 +1630,6 @@
 }
 #endif
 
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-
-#ifndef CONFIG_HL_SUPPORT
-/**
- * htt_mon_rx_handle_amsdu_packet() - Handle consecutive fragments of amsdu
- * @msdu: pointer to first msdu of amsdu
- * @pdev: Handle to htt_pdev_handle
- * @msg_word: Input and output variable, so pointer to HTT msg pointer
- * @amsdu_len: remaining length of all N-1 msdu msdu's
- * @frag_cnt: number of frags handled
- *
- * This function handles the (N-1) msdu's of amsdu, N'th msdu is already
- * handled by calling function. N-1 msdu's are tied using frags_list.
- * msdu_info field updated by FW indicates if this is last msdu. All the
- * msdu's before last msdu will be of MAX payload.
- *
- * Return: 1 on success and 0 on failure.
- */
-static
-int htt_mon_rx_handle_amsdu_packet(qdf_nbuf_t msdu, htt_pdev_handle pdev,
-				   uint32_t **msg_word, uint32_t amsdu_len,
-				   uint32_t *frag_cnt)
-{
-	qdf_nbuf_t frag_nbuf;
-	qdf_nbuf_t prev_frag_nbuf;
-	uint32_t len;
-	uint32_t last_frag;
-	qdf_dma_addr_t paddr;
-
-	*msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
-	paddr = htt_rx_in_ord_paddr_get(*msg_word);
-	frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, paddr);
-	if (qdf_unlikely(NULL == frag_nbuf)) {
-		qdf_print("%s: netbuf pop failed!\n", __func__);
-		return 0;
-	}
-	*frag_cnt = *frag_cnt + 1;
-	last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)*msg_word)->
-		msdu_info;
-	qdf_nbuf_append_ext_list(msdu, frag_nbuf, amsdu_len);
-	qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
-	qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
-	/* For msdu's other than parent will not have htt_host_rx_desc_base */
-	len = MIN(amsdu_len, HTT_RX_BUF_SIZE);
-	amsdu_len -= len;
-	qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
-
-	HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
-					QDF_TRACE_LEVEL_INFO_HIGH,
-					qdf_nbuf_data(frag_nbuf),
-					qdf_nbuf_len(frag_nbuf)));
-	prev_frag_nbuf = frag_nbuf;
-	while (!last_frag) {
-		*msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
-		paddr = htt_rx_in_ord_paddr_get(*msg_word);
-		frag_nbuf = htt_rx_in_order_netbuf_pop(pdev, paddr);
-		last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
-			     *msg_word)->msdu_info;
-
-		if (qdf_unlikely(NULL == frag_nbuf)) {
-			qdf_print("%s: netbuf pop failed!\n", __func__);
-			prev_frag_nbuf->next = NULL;
-			return 0;
-		}
-		*frag_cnt = *frag_cnt + 1;
-		qdf_nbuf_set_pktlen(frag_nbuf, HTT_RX_BUF_SIZE);
-		qdf_nbuf_unmap(pdev->osdev, frag_nbuf, QDF_DMA_FROM_DEVICE);
-
-		len = MIN(amsdu_len, HTT_RX_BUF_SIZE);
-		amsdu_len -= len;
-		qdf_nbuf_trim_tail(frag_nbuf, HTT_RX_BUF_SIZE - len);
-		HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
-						QDF_TRACE_LEVEL_INFO_HIGH,
-						qdf_nbuf_data(frag_nbuf),
-						qdf_nbuf_len(frag_nbuf)));
-
-		qdf_nbuf_set_next(prev_frag_nbuf, frag_nbuf);
-		prev_frag_nbuf = frag_nbuf;
-	}
-	qdf_nbuf_set_next(prev_frag_nbuf, NULL);
-	return 1;
-}
-
-#define SHORT_PREAMBLE 1
-#define LONG_PREAMBLE  0
-#ifdef HELIUMPLUS
-/**
- * htt_rx_get_rate() - get rate info in terms of 500Kbps from htt_rx_desc
- * @l_sig_rate_select: OFDM or CCK rate
- * @l_sig_rate:
- *
- * If l_sig_rate_select is 0:
- * 0x8: OFDM 48 Mbps
- * 0x9: OFDM 24 Mbps
- * 0xA: OFDM 12 Mbps
- * 0xB: OFDM 6 Mbps
- * 0xC: OFDM 54 Mbps
- * 0xD: OFDM 36 Mbps
- * 0xE: OFDM 18 Mbps
- * 0xF: OFDM 9 Mbps
- * If l_sig_rate_select is 1:
- * 0x1:  DSSS 1 Mbps long preamble
- * 0x2:  DSSS 2 Mbps long preamble
- * 0x3:  CCK 5.5 Mbps long preamble
- * 0x4:  CCK 11 Mbps long preamble
- * 0x5:  DSSS 2 Mbps short preamble
- * 0x6:  CCK 5.5 Mbps
- * 0x7:  CCK 11 Mbps short  preamble
- *
- * Return: rate interms of 500Kbps.
- */
-static unsigned char htt_rx_get_rate(uint32_t l_sig_rate_select,
-					uint32_t l_sig_rate, uint8_t *preamble)
-{
-	char ret = 0x0;
-	*preamble = SHORT_PREAMBLE;
-	if (l_sig_rate_select == 0) {
-		switch (l_sig_rate) {
-		case 0x8:
-			ret = 0x60;
-			break;
-		case 0x9:
-			ret = 0x30;
-			break;
-		case 0xA:
-			ret = 0x18;
-			break;
-		case 0xB:
-			ret = 0x0c;
-			break;
-		case 0xC:
-			ret = 0x6c;
-			break;
-		case 0xD:
-			ret = 0x48;
-			break;
-		case 0xE:
-			ret = 0x24;
-			break;
-		case 0xF:
-			ret = 0x12;
-			break;
-		default:
-			break;
-		}
-	} else if (l_sig_rate_select == 1) {
-		switch (l_sig_rate) {
-		case 0x1:
-			ret = 0x2;
-			*preamble = LONG_PREAMBLE;
-			break;
-		case 0x2:
-			ret = 0x4;
-			*preamble = LONG_PREAMBLE;
-			break;
-		case 0x3:
-			ret = 0xB;
-			*preamble = LONG_PREAMBLE;
-			break;
-		case 0x4:
-			ret = 0x16;
-			*preamble = LONG_PREAMBLE;
-			break;
-		case 0x5:
-			ret = 0x4;
-			break;
-		case 0x6:
-			ret = 0xB;
-			break;
-		case 0x7:
-			ret = 0x16;
-			break;
-		default:
-			break;
-		}
-	} else {
-		qdf_print("Invalid rate info\n");
-	}
-	return ret;
-}
-#else
-/**
- * htt_rx_get_rate() - get rate info in terms of 500Kbps from htt_rx_desc
- * @l_sig_rate_select: OFDM or CCK rate
- * @l_sig_rate:
- *
- * If l_sig_rate_select is 0:
- * 0x8: OFDM 48 Mbps
- * 0x9: OFDM 24 Mbps
- * 0xA: OFDM 12 Mbps
- * 0xB: OFDM 6 Mbps
- * 0xC: OFDM 54 Mbps
- * 0xD: OFDM 36 Mbps
- * 0xE: OFDM 18 Mbps
- * 0xF: OFDM 9 Mbps
- * If l_sig_rate_select is 1:
- * 0x8: CCK 11 Mbps long preamble
- *  0x9: CCK 5.5 Mbps long preamble
- * 0xA: CCK 2 Mbps long preamble
- * 0xB: CCK 1 Mbps long preamble
- * 0xC: CCK 11 Mbps short preamble
- * 0xD: CCK 5.5 Mbps short preamble
- * 0xE: CCK 2 Mbps short preamble
- *
- * Return: rate interms of 500Kbps.
- */
-static unsigned char htt_rx_get_rate(uint32_t l_sig_rate_select,
-					uint32_t l_sig_rate, uint8_t *preamble)
-{
-	char ret = 0x0;
-	*preamble = SHORT_PREAMBLE;
-	if (l_sig_rate_select == 0) {
-		switch (l_sig_rate) {
-		case 0x8:
-			ret = 0x60;
-			break;
-		case 0x9:
-			ret = 0x30;
-			break;
-		case 0xA:
-			ret = 0x18;
-			break;
-		case 0xB:
-			ret = 0x0c;
-			break;
-		case 0xC:
-			ret = 0x6c;
-			break;
-		case 0xD:
-			ret = 0x48;
-			break;
-		case 0xE:
-			ret = 0x24;
-			break;
-		case 0xF:
-			ret = 0x12;
-			break;
-		default:
-			break;
-		}
-	} else if (l_sig_rate_select == 1) {
-		switch (l_sig_rate) {
-		case 0x8:
-			ret = 0x16;
-			*preamble = LONG_PREAMBLE;
-			break;
-		case 0x9:
-			ret = 0x0B;
-			*preamble = LONG_PREAMBLE;
-			break;
-		case 0xA:
-			ret = 0x4;
-			*preamble = LONG_PREAMBLE;
-			break;
-		case 0xB:
-			ret = 0x02;
-			*preamble = LONG_PREAMBLE;
-			break;
-		case 0xC:
-			ret = 0x16;
-			break;
-		case 0xD:
-			ret = 0x0B;
-			break;
-		case 0xE:
-			ret = 0x04;
-			break;
-		default:
-			break;
-		}
-	} else {
-		qdf_print("Invalid rate info\n");
-	}
-	return ret;
-}
-#endif /* HELIUMPLUS */
-/**
- * htt_mon_rx_get_phy_info() - Get phy info
- * @rx_desc: Pointer to struct htt_host_rx_desc_base
- * @rx_status: Return variable updated with phy_info in rx_status
- *
- * Return: None
- */
-static void htt_mon_rx_get_phy_info(struct htt_host_rx_desc_base *rx_desc,
-				    struct mon_rx_status *rx_status)
-{
-	uint8_t preamble = 0;
-	uint8_t preamble_type = rx_desc->ppdu_start.preamble_type;
-	uint8_t mcs = 0, nss = 0, sgi = 0, bw = 0, beamformed = 0;
-	uint16_t vht_flags = 0, ht_flags = 0;
-	uint32_t l_sig_rate_select = rx_desc->ppdu_start.l_sig_rate_select;
-	uint32_t l_sig_rate = rx_desc->ppdu_start.l_sig_rate;
-	bool is_stbc = 0, ldpc = 0;
-
-	switch (preamble_type) {
-	case 4:
-	/* legacy */
-		rx_status->rate = htt_rx_get_rate(l_sig_rate_select, l_sig_rate,
-						&preamble);
-		break;
-	case 8:
-		is_stbc = ((VHT_SIG_A_2(rx_desc) >> 4) & 3);
-		/* fallthrough */
-	case 9:
-		ht_flags = 1;
-		sgi = (VHT_SIG_A_2(rx_desc) >> 7) & 0x01;
-		bw = (VHT_SIG_A_1(rx_desc) >> 7) & 0x01;
-		mcs = (VHT_SIG_A_1(rx_desc) & 0x7f);
-		nss = mcs>>3;
-		beamformed =
-			(VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
-		break;
-	case 0x0c:
-		is_stbc = (VHT_SIG_A_2(rx_desc) >> 3) & 1;
-		ldpc = (VHT_SIG_A_2(rx_desc) >> 2) & 1;
-		/* fallthrough */
-	case 0x0d:
-	{
-		uint8_t gid_in_sig = ((VHT_SIG_A_1(rx_desc) >> 4) & 0x3f);
-
-		vht_flags = 1;
-		sgi = VHT_SIG_A_2(rx_desc) & 0x01;
-		bw = (VHT_SIG_A_1(rx_desc) & 0x03);
-		if (gid_in_sig == 0 || gid_in_sig == 63) {
-			/* SU case */
-			mcs = (VHT_SIG_A_2(rx_desc) >> 4) &
-				0xf;
-			nss = (VHT_SIG_A_1(rx_desc) >> 10) &
-				0x7;
-		} else {
-			/* MU case */
-			uint8_t sta_user_pos =
-				(uint8_t)((rx_desc->ppdu_start.reserved_4a >> 8)
-					  & 0x3);
-			mcs = (rx_desc->ppdu_start.vht_sig_b >> 16);
-			if (bw >= 2)
-				mcs >>= 3;
-			else if (bw > 0)
-				mcs >>= 1;
-			mcs &= 0xf;
-			nss = (((VHT_SIG_A_1(rx_desc) >> 10) +
-				sta_user_pos * 3) & 0x7);
-		}
-		beamformed = (VHT_SIG_A_2(rx_desc) >> 8) & 0x1;
-	}
-		/* fallthrough */
-	default:
-		break;
-	}
-
-	rx_status->mcs = mcs;
-	rx_status->bw = bw;
-	rx_status->nr_ant = nss;
-	rx_status->is_stbc = is_stbc;
-	rx_status->sgi = sgi;
-	rx_status->ldpc = ldpc;
-	rx_status->beamformed = beamformed;
-	rx_status->vht_flag_values3[0] = mcs << 0x4 | (nss + 1);
-	rx_status->ht_flags = ht_flags;
-	rx_status->vht_flags = vht_flags;
-	rx_status->rtap_flags |= ((preamble == SHORT_PREAMBLE) ? BIT(1) : 0);
-	if (bw == 0)
-		rx_status->vht_flag_values2 = 0;
-	else if (bw == 1)
-		rx_status->vht_flag_values2 = 1;
-	else if (bw == 2)
-		rx_status->vht_flag_values2 = 4;
-}
-
-/**
- * htt_mon_rx_get_rtap_flags() - Get radiotap flags
- * @rx_desc: Pointer to struct htt_host_rx_desc_base
- *
- * Return: Bitmapped radiotap flags.
- */
-static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc)
-{
-	uint8_t rtap_flags = 0;
-
-	/* WEP40 || WEP104 || WEP128 */
-	if (rx_desc->mpdu_start.encrypt_type == 0 ||
-	    rx_desc->mpdu_start.encrypt_type == 1 ||
-	    rx_desc->mpdu_start.encrypt_type == 3)
-		rtap_flags |= BIT(2);
-
-	/* IEEE80211_RADIOTAP_F_FRAG */
-	if (rx_desc->attention.fragment)
-		rtap_flags |= BIT(3);
-
-	/* IEEE80211_RADIOTAP_F_FCS */
-	rtap_flags |= BIT(4);
-
-	/* IEEE80211_RADIOTAP_F_BADFCS */
-	if (rx_desc->mpdu_end.fcs_err)
-		rtap_flags |= BIT(6);
-
-	return rtap_flags;
-}
-
-/**
- * htt_rx_mon_get_rx_status() - Update information about the rx status,
- * which is used later for radiotap updation.
- * @rx_desc: Pointer to struct htt_host_rx_desc_base
- * @rx_status: Return variable updated with rx_status
- *
- * Return: None
- */
-static void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
-				     struct htt_host_rx_desc_base *rx_desc,
-				     struct mon_rx_status *rx_status)
-{
-	uint16_t channel_flags = 0;
-	struct mon_channel *ch_info = &pdev->mon_ch_info;
-
-	rx_status->tsft = (u_int64_t)TSF_TIMESTAMP(rx_desc);
-	rx_status->chan_freq = ch_info->ch_freq;
-	rx_status->chan_num = ch_info->ch_num;
-	htt_mon_rx_get_phy_info(rx_desc, rx_status);
-	rx_status->rtap_flags |= htt_mon_rx_get_rtap_flags(rx_desc);
-	channel_flags |= rx_desc->ppdu_start.l_sig_rate_select ?
-		IEEE80211_CHAN_CCK : IEEE80211_CHAN_OFDM;
-	channel_flags |=
-		(cds_chan_to_band(ch_info->ch_num) == CDS_BAND_2GHZ ?
-		IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ);
-
-	rx_status->chan_flags = channel_flags;
-	rx_status->ant_signal_db = rx_desc->ppdu_start.rssi_comb;
-}
-#endif
-
-#ifdef RX_HASH_DEBUG
-#define HTT_RX_CHECK_MSDU_COUNT(msdu_count) HTT_ASSERT_ALWAYS(msdu_count)
-#else
-#define HTT_RX_CHECK_MSDU_COUNT(msdu_count)     /* no-op */
-#endif
-
-#ifndef CONFIG_HL_SUPPORT
-/**
- * htt_rx_mon_amsdu_rx_in_order_pop_ll() - Monitor mode HTT Rx in order pop
- * function
- * @pdev: Handle to htt_pdev_handle
- * @rx_ind_msg: In order indication message.
- * @head_msdu: Return variable pointing to head msdu.
- * @tail_msdu: Return variable pointing to tail msdu.
- *
- * This function pops the msdu based on paddr:length of inorder indication
- * message.
- *
- * Return: 1 for success, 0 on failure.
- */
-static int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
-					       qdf_nbuf_t rx_ind_msg,
-					       qdf_nbuf_t *head_msdu,
-					       qdf_nbuf_t *tail_msdu,
-					       uint32_t *replenish_cnt)
-{
-	qdf_nbuf_t msdu, next, prev = NULL;
-	uint8_t *rx_ind_data;
-	uint32_t *msg_word;
-	uint32_t msdu_count;
-	struct htt_host_rx_desc_base *rx_desc;
-	struct mon_rx_status rx_status = {0};
-	uint32_t amsdu_len;
-	uint32_t len;
-	uint32_t last_frag;
-	qdf_dma_addr_t paddr;
-
-	HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0);
-
-	rx_ind_data = qdf_nbuf_data(rx_ind_msg);
-	msg_word = (uint32_t *)rx_ind_data;
-
-	*replenish_cnt = 0;
-	HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
-					QDF_TRACE_LEVEL_INFO_HIGH,
-					(void *)rx_ind_data,
-					(int)qdf_nbuf_len(rx_ind_msg)));
-
-	/* Get the total number of MSDUs */
-	msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1));
-	HTT_RX_CHECK_MSDU_COUNT(msdu_count);
-
-	msg_word = (uint32_t *)(rx_ind_data +
-				 HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES);
-	paddr = htt_rx_in_ord_paddr_get(msg_word);
-	msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
-
-	if (qdf_unlikely(NULL == msdu)) {
-		qdf_print("%s: netbuf pop failed!\n", __func__);
-		*tail_msdu = NULL;
-		return 0;
-	}
-	*replenish_cnt = *replenish_cnt + 1;
-
-	while (msdu_count > 0) {
-
-		msdu_count--;
-		/*
-		 * Set the netbuf length to be the entire buffer length
-		 * initially, so the unmap will unmap the entire buffer.
-		 */
-		qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
-		qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
-
-		/*
-		 * cache consistency has been taken care of by the
-		 * qdf_nbuf_unmap
-		 */
-		rx_desc = htt_rx_desc(msdu);
-		if ((unsigned int)(*(uint32_t *)&rx_desc->attention) &
-				RX_DESC_ATTN_MPDU_LEN_ERR_BIT) {
-			qdf_nbuf_free(msdu);
-			last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
-			     msg_word)->msdu_info;
-			while (!last_frag) {
-				msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
-				paddr = htt_rx_in_ord_paddr_get(msg_word);
-				msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
-				last_frag = ((struct
-					htt_rx_in_ord_paddr_ind_msdu_t *)
-					msg_word)->msdu_info;
-				if (qdf_unlikely(!msdu)) {
-					qdf_print("%s: netbuf pop failed!\n",
-						  __func__);
-					return 0;
-				}
-				*replenish_cnt = *replenish_cnt + 1;
-				qdf_nbuf_unmap(pdev->osdev, msdu,
-					       QDF_DMA_FROM_DEVICE);
-				qdf_nbuf_free(msdu);
-			}
-			msdu = prev;
-			goto next_pop;
-		}
-
-		if (!prev)
-			(*head_msdu) = msdu;
-		prev = msdu;
-
-		HTT_PKT_DUMP(htt_print_rx_desc(rx_desc));
-		/*
-		 * Make the netbuf's data pointer point to the payload rather
-		 * than the descriptor.
-		 */
-		htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status);
-		/*
-		 * For certain platform, 350 bytes of headroom is already
-		 * appended to accommodate radiotap header but
-		 * qdf_nbuf_update_radiotap() API again will try to create
-		 * a room for radiotap header. To make our design simple
-		 * let qdf_nbuf_update_radiotap() API create a room for radiotap
-		 * header and update it, do qdf_nbuf_pull_head() operation and
-		 * pull 350 bytes of headroom.
-		 *
-		 *
-		 *
-		 *               (SKB buffer)
-		 * skb->head --> +-----------+ <-- skb->data
-		 *               |           |     (Before pulling headroom)
-		 *               |           |
-		 *               |   HEAD    |  350 bytes of headroom
-		 *               |           |
-		 *               |           |
-		 *               +-----------+ <-- skb->data
-		 *               |           |     (After pulling headroom)
-		 *               |           |
-		 *               |   DATA    |
-		 *               |           |
-		 *               |           |
-		 *               +-----------+
-		 *               |           |
-		 *               |           |
-		 *               |   TAIL    |
-		 *               |           |
-		 *               |           |
-		 *               +-----------+
-		 *
-		 */
-		if (qdf_nbuf_head(msdu) == qdf_nbuf_data(msdu))
-			qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION);
-		qdf_nbuf_update_radiotap(&rx_status, msdu,
-						  HTT_RX_STD_DESC_RESERVATION);
-		amsdu_len = HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(*(msg_word +
-						NEXT_FIELD_OFFSET_IN32));
-
-		/*
-		 * MAX_RX_PAYLOAD_SZ when we have AMSDU packet. amsdu_len in
-		 * which case is the total length of sum of all AMSDU's
-		 */
-		len = MIN(amsdu_len, MAX_RX_PAYLOAD_SZ);
-		amsdu_len -= len;
-		qdf_nbuf_trim_tail(msdu,
-			   HTT_RX_BUF_SIZE -
-			   (RX_STD_DESC_SIZE + len));
-
-
-		HTT_PKT_DUMP(qdf_trace_hex_dump(QDF_MODULE_ID_TXRX,
-						QDF_TRACE_LEVEL_INFO_HIGH,
-						qdf_nbuf_data(msdu),
-						qdf_nbuf_len(msdu)));
-		last_frag = ((struct htt_rx_in_ord_paddr_ind_msdu_t *)
-			     msg_word)->msdu_info;
-
-		/* Handle amsdu packet */
-		if (!last_frag) {
-			/*
-			 * For AMSDU packet msdu->len is sum of all the msdu's
-			 * length, msdu->data_len is sum of length's of
-			 * remaining msdu's other than parent.
-			 */
-			if (!htt_mon_rx_handle_amsdu_packet(msdu, pdev,
-							    &msg_word,
-							    amsdu_len,
-							    replenish_cnt)) {
-				qdf_print("%s: failed to handle amsdu packet\n",
-					     __func__);
-				return 0;
-			}
-		}
-
-next_pop:
-		/* check if this is the last msdu */
-		if (msdu_count) {
-			msg_word += HTT_RX_IN_ORD_PADDR_IND_MSDU_DWORDS;
-			paddr = htt_rx_in_ord_paddr_get(msg_word);
-			next = htt_rx_in_order_netbuf_pop(pdev, paddr);
-			if (qdf_unlikely(NULL == next)) {
-				qdf_print("%s: netbuf pop failed!\n",
-					     __func__);
-				*tail_msdu = NULL;
-				return 0;
-			}
-			*replenish_cnt = *replenish_cnt + 1;
-			if (msdu)
-				qdf_nbuf_set_next(msdu, next);
-			msdu = next;
-		} else {
-			*tail_msdu = msdu;
-			if (msdu)
-				qdf_nbuf_set_next(msdu, NULL);
-		}
-	}
-
-	return 1;
-}
-#endif
-
-/**
- * htt_rx_mon_note_capture_channel() - Make note of channel to update in
- * radiotap
- * @pdev: handle to htt_pdev
- * @mon_ch: capture channel number.
- *
- * Return: None
- */
-void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch)
-{
-	struct mon_channel *ch_info = &pdev->mon_ch_info;
-
-	ch_info->ch_num = mon_ch;
-	ch_info->ch_freq = cds_chan_to_freq(mon_ch);
-}
-
 uint32_t htt_rx_amsdu_rx_in_order_get_pktlog(qdf_nbuf_t rx_ind_msg)
 {
 	uint32_t *msg_word;
@@ -2635,384 +1868,6 @@
 }
 #endif
 
-/* FIXME: This is a HW definition not provded by HW, where does it go ? */
-enum {
-	HW_RX_DECAP_FORMAT_RAW = 0,
-	HW_RX_DECAP_FORMAT_NWIFI,
-	HW_RX_DECAP_FORMAT_8023,
-	HW_RX_DECAP_FORMAT_ETH2,
-};
-
-#define HTT_FCS_LEN (4)
-
-#if !defined(QCA6290_HEADERS_DEF)
-static void
-htt_rx_parse_ppdu_start_status(struct htt_host_rx_desc_base *rx_desc,
-			       struct ieee80211_rx_status *rs)
-{
-
-	struct rx_ppdu_start *ppdu_start = &rx_desc->ppdu_start;
-
-	/* RSSI */
-	rs->rs_rssi = ppdu_start->rssi_comb;
-
-	/* PHY rate */
-	/*
-	 * rs_ratephy coding
-	 * [b3 - b0]
-	 * 0 -> OFDM
-	 * 1 -> CCK
-	 * 2 -> HT
-	 * 3 -> VHT
-	 * OFDM / CCK
-	 * [b7  - b4 ] => LSIG rate
-	 * [b23 - b8 ] => service field
-	 * (b'12 static/dynamic,
-	 * b'14..b'13 BW for VHT)
-	 * [b31 - b24 ] => Reserved
-	 * HT / VHT
-	 * [b15 - b4 ] => SIG A_2 12 LSBs
-	 * [b31 - b16] => SIG A_1 16 LSBs
-	 */
-	if (ppdu_start->preamble_type == 0x4) {
-		rs->rs_ratephy = ppdu_start->l_sig_rate_select;
-		rs->rs_ratephy |= ppdu_start->l_sig_rate << 4;
-		rs->rs_ratephy |= ppdu_start->service << 8;
-	} else {
-		rs->rs_ratephy = (ppdu_start->preamble_type & 0x4) ? 3 : 2;
-#ifdef HELIUMPLUS
-		rs->rs_ratephy |=
-			(ppdu_start->ht_sig_vht_sig_ah_sig_a_2 & 0xFFF) << 4;
-		rs->rs_ratephy |=
-			(ppdu_start->ht_sig_vht_sig_ah_sig_a_1 & 0xFFFF) << 16;
-#else
-		rs->rs_ratephy |= (ppdu_start->ht_sig_vht_sig_a_2 & 0xFFF) << 4;
-		rs->rs_ratephy |=
-			(ppdu_start->ht_sig_vht_sig_a_1 & 0xFFFF) << 16;
-#endif
-	}
-}
-
-/* Util fake function that has same prototype as qdf_nbuf_clone that just
- * returns the same nbuf
- */
-static qdf_nbuf_t htt_rx_qdf_noclone_buf(qdf_nbuf_t buf)
-{
-	return buf;
-}
-
-/* This function is used by montior mode code to restitch an MSDU list
- * corresponding to an MPDU back into an MPDU by linking up the skbs.
- */
-qdf_nbuf_t
-htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
-				qdf_nbuf_t head_msdu,
-				struct ieee80211_rx_status *rx_status,
-				unsigned int clone_not_reqd)
-{
-
-	qdf_nbuf_t msdu, mpdu_buf, prev_buf, msdu_orig, head_frag_list_cloned;
-	unsigned int decap_format, wifi_hdr_len, sec_hdr_len, msdu_llc_len,
-		 mpdu_buf_len, decap_hdr_pull_bytes, frag_list_sum_len, dir,
-		 is_amsdu, is_first_frag, amsdu_pad, msdu_len;
-	struct htt_host_rx_desc_base *rx_desc;
-	char *hdr_desc;
-	unsigned char *dest;
-	struct ieee80211_frame *wh;
-	struct ieee80211_qoscntl *qos;
-
-	/* The nbuf has been pulled just beyond the status and points to the
-	 * payload
-	 */
-	msdu_orig = head_msdu;
-	rx_desc = htt_rx_desc(msdu_orig);
-
-	/* Fill out the rx_status from the PPDU start and end fields */
-	if (rx_desc->attention.first_mpdu) {
-		htt_rx_parse_ppdu_start_status(rx_desc, rx_status);
-
-		/* The timestamp is no longer valid - It will be valid only for
-		 * the last MPDU
-		 */
-		rx_status->rs_tstamp.tsf = ~0;
-	}
-
-	decap_format =
-		GET_FIELD(&rx_desc->msdu_start, RX_MSDU_START_2_DECAP_FORMAT);
-
-	head_frag_list_cloned = NULL;
-
-	/* Easy case - The MSDU status indicates that this is a non-decapped
-	 * packet in RAW mode.
-	 * return
-	 */
-	if (decap_format == HW_RX_DECAP_FORMAT_RAW) {
-		/* Note that this path might suffer from headroom unavailabilty,
-		 * but the RX status is usually enough
-		 */
-		if (clone_not_reqd)
-			mpdu_buf = htt_rx_qdf_noclone_buf(head_msdu);
-		else
-			mpdu_buf = qdf_nbuf_clone(head_msdu);
-
-		if (!mpdu_buf)
-			goto mpdu_stitch_fail;
-
-		prev_buf = mpdu_buf;
-
-		frag_list_sum_len = 0;
-		is_first_frag = 1;
-		msdu_len = qdf_nbuf_len(mpdu_buf);
-
-		/* Drop the zero-length msdu */
-		if (!msdu_len)
-			goto mpdu_stitch_fail;
-
-		msdu_orig = qdf_nbuf_next(head_msdu);
-
-		while (msdu_orig) {
-
-			/* TODO: intra AMSDU padding - do we need it ??? */
-			if (clone_not_reqd)
-				msdu = htt_rx_qdf_noclone_buf(msdu_orig);
-			else
-				msdu = qdf_nbuf_clone(msdu_orig);
-
-			if (!msdu)
-				goto mpdu_stitch_fail;
-
-			if (is_first_frag) {
-				is_first_frag = 0;
-				head_frag_list_cloned = msdu;
-			}
-
-			msdu_len = qdf_nbuf_len(msdu);
-			/* Drop the zero-length msdu */
-			if (!msdu_len)
-				goto mpdu_stitch_fail;
-
-			frag_list_sum_len += msdu_len;
-
-			/* Maintain the linking of the cloned MSDUS */
-			qdf_nbuf_set_next_ext(prev_buf, msdu);
-
-			/* Move to the next */
-			prev_buf = msdu;
-			msdu_orig = qdf_nbuf_next(msdu_orig);
-		}
-
-		/* The last msdu length need be larger than HTT_FCS_LEN */
-		if (msdu_len < HTT_FCS_LEN)
-			goto mpdu_stitch_fail;
-
-		qdf_nbuf_trim_tail(prev_buf, HTT_FCS_LEN);
-
-		/* If there were more fragments to this RAW frame */
-		if (head_frag_list_cloned) {
-			qdf_nbuf_append_ext_list(mpdu_buf,
-						 head_frag_list_cloned,
-						 frag_list_sum_len);
-		}
-
-		goto mpdu_stitch_done;
-	}
-
-	/* Decap mode:
-	 * Calculate the amount of header in decapped packet to knock off based
-	 * on the decap type and the corresponding number of raw bytes to copy
-	 * status header
-	 */
-
-	hdr_desc = &rx_desc->rx_hdr_status[0];
-
-	/* Base size */
-	wifi_hdr_len = sizeof(struct ieee80211_frame);
-	wh = (struct ieee80211_frame *)hdr_desc;
-
-	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
-	if (dir == IEEE80211_FC1_DIR_DSTODS)
-		wifi_hdr_len += 6;
-
-	is_amsdu = 0;
-	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
-		qos = (struct ieee80211_qoscntl *)
-		      (hdr_desc + wifi_hdr_len);
-		wifi_hdr_len += 2;
-
-		is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU);
-	}
-
-	/* TODO: Any security headers associated with MPDU */
-	sec_hdr_len = 0;
-
-	/* MSDU related stuff LLC - AMSDU subframe header etc */
-	msdu_llc_len = is_amsdu ? (14 + 8) : 8;
-
-	mpdu_buf_len = wifi_hdr_len + sec_hdr_len + msdu_llc_len;
-
-	/* "Decap" header to remove from MSDU buffer */
-	decap_hdr_pull_bytes = 14;
-
-	/* Allocate a new nbuf for holding the 802.11 header retrieved from the
-	 * status of the now decapped first msdu. Leave enough headroom for
-	 * accomodating any radio-tap /prism like PHY header
-	 */
-#define HTT_MAX_MONITOR_HEADER (512)
-	mpdu_buf = qdf_nbuf_alloc(pdev->osdev,
-				  HTT_MAX_MONITOR_HEADER + mpdu_buf_len,
-				  HTT_MAX_MONITOR_HEADER, 4, false);
-
-	if (!mpdu_buf)
-		goto mpdu_stitch_fail;
-
-	/* Copy the MPDU related header and enc headers into the first buffer
-	 * - Note that there can be a 2 byte pad between heaader and enc header
-	 */
-
-	prev_buf = mpdu_buf;
-	dest = qdf_nbuf_put_tail(prev_buf, wifi_hdr_len);
-	if (!dest)
-		goto mpdu_stitch_fail;
-	qdf_mem_copy(dest, hdr_desc, wifi_hdr_len);
-	hdr_desc += wifi_hdr_len;
-
-	/* NOTE - This padding is present only in the RAW header status - not
-	 * when the MSDU data payload is in RAW format.
-	 */
-	/* Skip the "IV pad" */
-	if (wifi_hdr_len & 0x3)
-		hdr_desc += 2;
-
-	/* The first LLC len is copied into the MPDU buffer */
-	frag_list_sum_len = 0;
-	frag_list_sum_len -= msdu_llc_len;
-
-	msdu_orig = head_msdu;
-	is_first_frag = 1;
-	amsdu_pad = 0;
-
-	while (msdu_orig) {
-
-		/* TODO: intra AMSDU padding - do we need it ??? */
-
-		if (clone_not_reqd)
-			msdu = htt_rx_qdf_noclone_buf(msdu_orig);
-		else
-			msdu = qdf_nbuf_clone(msdu_orig);
-
-		if (!msdu)
-			goto mpdu_stitch_fail;
-
-		if (is_first_frag) {
-			is_first_frag = 0;
-			head_frag_list_cloned = msdu;
-		} else {
-
-			/* Maintain the linking of the cloned MSDUS */
-			qdf_nbuf_set_next_ext(prev_buf, msdu);
-
-			/* Reload the hdr ptr only on non-first MSDUs */
-			rx_desc = htt_rx_desc(msdu_orig);
-			hdr_desc = &rx_desc->rx_hdr_status[0];
-
-		}
-
-		/* Copy this buffers MSDU related status into the prev buffer */
-		dest = qdf_nbuf_put_tail(prev_buf, msdu_llc_len + amsdu_pad);
-		dest += amsdu_pad;
-		qdf_mem_copy(dest, hdr_desc, msdu_llc_len);
-
-		/* Push the MSDU buffer beyond the decap header */
-		qdf_nbuf_pull_head(msdu, decap_hdr_pull_bytes);
-		frag_list_sum_len +=
-			msdu_llc_len + qdf_nbuf_len(msdu) + amsdu_pad;
-
-		/*
-		 * Set up intra-AMSDU pad to be added to start of next buffer -
-		 * AMSDU pad is 4 byte pad on AMSDU subframe
-		 */
-		amsdu_pad = (msdu_llc_len + qdf_nbuf_len(msdu)) & 0x3;
-		amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
-
-		/*
-		 * TODO FIXME How do we handle MSDUs that have fraglist - Should
-		 * probably iterate all the frags cloning them along the way and
-		 * and also updating the prev_buf pointer
-		 */
-
-		/* Move to the next */
-		prev_buf = msdu;
-		msdu_orig = qdf_nbuf_next(msdu_orig);
-
-	}
-
-	/* TODO: Convert this to suitable qdf routines */
-	qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list_cloned,
-				 frag_list_sum_len);
-
-mpdu_stitch_done:
-	/* Check if this buffer contains the PPDU end status for TSF */
-	if (rx_desc->attention.last_mpdu)
-#ifdef HELIUMPLUS
-		rx_status->rs_tstamp.tsf =
-			rx_desc->ppdu_end.rx_pkt_end.phy_timestamp_1_lower_32;
-#else
-		rx_status->rs_tstamp.tsf = rx_desc->ppdu_end.tsf_timestamp;
-#endif
-	/* All the nbufs have been linked into the ext list and
-	   then unlink the nbuf list */
-	if (clone_not_reqd) {
-		msdu = head_msdu;
-		while (msdu) {
-			msdu_orig = msdu;
-			msdu = qdf_nbuf_next(msdu);
-			qdf_nbuf_set_next(msdu_orig, NULL);
-		}
-	}
-
-	return mpdu_buf;
-
-mpdu_stitch_fail:
-	/* Free these alloced buffers and the orig buffers in non-clone case */
-	if (!clone_not_reqd) {
-		/* Free the head buffer */
-		if (mpdu_buf)
-			qdf_nbuf_free(mpdu_buf);
-
-		/* Free the partial list */
-		while (head_frag_list_cloned) {
-			msdu = head_frag_list_cloned;
-			head_frag_list_cloned =
-				qdf_nbuf_next_ext(head_frag_list_cloned);
-			qdf_nbuf_free(msdu);
-		}
-	} else {
-		/* Free the alloced head buffer */
-		if (decap_format != HW_RX_DECAP_FORMAT_RAW)
-			if (mpdu_buf)
-				qdf_nbuf_free(mpdu_buf);
-
-		/* Free the orig buffers */
-		msdu = head_msdu;
-		while (msdu) {
-			msdu_orig = msdu;
-			msdu = qdf_nbuf_next(msdu);
-			qdf_nbuf_free(msdu_orig);
-		}
-	}
-
-	return NULL;
-}
-#else
-qdf_nbuf_t
-htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
-				qdf_nbuf_t head_msdu,
-				struct ieee80211_rx_status *rx_status,
-				unsigned clone_not_reqd)
-{
-	return NULL;
-}
-#endif
 int16_t htt_rx_mpdu_desc_rssi_dbm(htt_pdev_handle pdev, void *mpdu_desc)
 {
 	/*
diff --git a/core/dp/ol/inc/ol_htt_api.h b/core/dp/ol/inc/ol_htt_api.h
index 3ba7fd5..cb51c8f 100644
--- a/core/dp/ol/inc/ol_htt_api.h
+++ b/core/dp/ol/inc/ol_htt_api.h
@@ -360,9 +360,17 @@
 }
 #endif /* IPA_OFFLOAD */
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch);
 
 void ol_htt_mon_note_chan(struct cdp_pdev *ppdev, int mon_ch);
+#else
+static inline
+void htt_rx_mon_note_capture_channel(htt_pdev_handle pdev, int mon_ch) {}
+
+static inline
+void ol_htt_mon_note_chan(struct cdp_pdev *ppdev, int mon_ch) {}
+#endif
 
 #if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
 
diff --git a/core/dp/ol/inc/ol_htt_rx_api.h b/core/dp/ol/inc/ol_htt_rx_api.h
index 191ab46..fab4291 100644
--- a/core/dp/ol/inc/ol_htt_rx_api.h
+++ b/core/dp/ol/inc/ol_htt_rx_api.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 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
@@ -824,11 +824,22 @@
  *      list, else operates on a cloned nbuf
  * @return network buffer handle to the MPDU
  */
+#if !defined(QCA6290_HEADERS_DEF) && defined(FEATURE_MONITOR_MODE_SUPPORT)
 qdf_nbuf_t
 htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
 				qdf_nbuf_t head_msdu,
 				struct ieee80211_rx_status *rx_status,
 				unsigned clone_not_reqd);
+#else
+static inline qdf_nbuf_t
+htt_rx_restitch_mpdu_from_msdus(htt_pdev_handle pdev,
+				qdf_nbuf_t head_msdu,
+				struct ieee80211_rx_status *rx_status,
+				unsigned clone_not_reqd)
+{
+	return NULL;
+}
+#endif
 
 /**
  * @brief Return the sequence number of MPDUs to flush.
diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c
index f8218fa..6b1da8f 100644
--- a/core/dp/txrx/ol_rx.c
+++ b/core/dp/txrx/ol_rx.c
@@ -1718,6 +1718,7 @@
 }
 #endif
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 /**
  * ol_htt_mon_note_chan() - Update monitor channel information
  * @pdev:  handle to the physical device
@@ -1731,6 +1732,7 @@
 
 	htt_rx_mon_note_capture_channel(pdev->htt_pdev, mon_ch);
 }
+#endif
 
 #ifdef NEVERDEFINED
 /**
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 8bcffb4..a44339c 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -3176,6 +3176,7 @@
  */
 void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool disconnecting);
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 /**
  * wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface.
  * @adapter: Handle to adapter
@@ -3186,6 +3187,14 @@
  */
 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
 			  uint32_t bandwidth);
+#else
+static inline
+int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
+			  uint32_t bandwidth)
+{
+	return 0;
+}
+#endif
 
 /**
  * hdd_wlan_get_version() - Get version information
diff --git a/core/hdd/inc/wlan_hdd_tx_rx.h b/core/hdd/inc/wlan_hdd_tx_rx.h
index ba842d0..193cb15 100644
--- a/core/hdd/inc/wlan_hdd_tx_rx.h
+++ b/core/hdd/inc/wlan_hdd_tx_rx.h
@@ -181,7 +181,17 @@
 const char *hdd_action_type_to_string(enum netif_action_type action);
 void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
 		enum netif_action_type action, enum netif_reason_type reason);
+
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 int hdd_set_mon_rx_cb(struct net_device *dev);
+#else
+static inline
+int hdd_set_mon_rx_cb(struct net_device *dev)
+{
+	return 0;
+}
+#endif
+
 void hdd_send_rps_ind(struct hdd_adapter *adapter);
 void hdd_send_rps_disable_ind(struct hdd_adapter *adapter);
 void wlan_hdd_classify_pkt(struct sk_buff *skb);
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index bf22e21..d00c04e 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -17541,6 +17541,64 @@
 }
 #endif
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+static
+void hdd_mon_select_cbmode(struct hdd_adapter *adapter,
+			   uint8_t operationChannel,
+			   struct ch_params *ch_params)
+{
+	struct hdd_station_ctx *station_ctx =
+			 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_mon_set_ch_info *ch_info = &station_ctx->ch_info;
+	enum hdd_dot11_mode hdd_dot11_mode;
+	uint8_t ini_dot11_mode =
+			(WLAN_HDD_GET_CTX(adapter))->config->dot11Mode;
+
+	hdd_debug("Dot11Mode is %u", ini_dot11_mode);
+	switch (ini_dot11_mode) {
+	case eHDD_DOT11_MODE_AUTO:
+	case eHDD_DOT11_MODE_11ax:
+	case eHDD_DOT11_MODE_11ax_ONLY:
+		if (sme_is_feature_supported_by_fw(DOT11AX))
+			hdd_dot11_mode = eHDD_DOT11_MODE_11ax;
+		else if (sme_is_feature_supported_by_fw(DOT11AC))
+			hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
+		else
+			hdd_dot11_mode = eHDD_DOT11_MODE_11n;
+		break;
+	case eHDD_DOT11_MODE_11ac:
+	case eHDD_DOT11_MODE_11ac_ONLY:
+		if (sme_is_feature_supported_by_fw(DOT11AC))
+			hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
+		else
+			hdd_dot11_mode = eHDD_DOT11_MODE_11n;
+		break;
+	case eHDD_DOT11_MODE_11n:
+	case eHDD_DOT11_MODE_11n_ONLY:
+		hdd_dot11_mode = eHDD_DOT11_MODE_11n;
+		break;
+	default:
+		hdd_dot11_mode = ini_dot11_mode;
+		break;
+	}
+	ch_info->channel_width = ch_params->ch_width;
+	ch_info->phy_mode =
+		hdd_cfg_xlate_to_csr_phy_mode(hdd_dot11_mode);
+	ch_info->channel = operationChannel;
+	ch_info->cb_mode = ch_params->ch_width;
+	hdd_debug("ch_info width %d, phymode %d channel %d",
+		  ch_info->channel_width, ch_info->phy_mode,
+		  ch_info->channel);
+}
+#else
+static
+void hdd_mon_select_cbmode(struct hdd_adapter *adapter,
+			   uint8_t operationChannel,
+			   struct ch_params *ch_params)
+{
+}
+#endif
+
 /**
  * hdd_select_cbmode() - select channel bonding mode
  * @adapter: Pointer to adapter
@@ -17552,8 +17610,6 @@
 void hdd_select_cbmode(struct hdd_adapter *adapter, uint8_t operationChannel,
 			struct ch_params *ch_params)
 {
-	struct hdd_station_ctx *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
-	struct hdd_mon_set_ch_info *ch_info = &station_ctx->ch_info;
 	uint8_t sec_ch = 0;
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
@@ -17573,47 +17629,8 @@
 	wlan_reg_set_channel_params(hdd_ctx->hdd_pdev, operationChannel,
 			sec_ch, ch_params);
 
-	if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) {
-		enum hdd_dot11_mode hdd_dot11_mode;
-		uint8_t iniDot11Mode =
-			(WLAN_HDD_GET_CTX(adapter))->config->dot11Mode;
-
-		hdd_debug("Dot11Mode is %u", iniDot11Mode);
-		switch (iniDot11Mode) {
-		case eHDD_DOT11_MODE_AUTO:
-		case eHDD_DOT11_MODE_11ax:
-		case eHDD_DOT11_MODE_11ax_ONLY:
-			if (sme_is_feature_supported_by_fw(DOT11AX))
-				hdd_dot11_mode = eHDD_DOT11_MODE_11ax;
-			else if (sme_is_feature_supported_by_fw(DOT11AC))
-				hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
-			else
-				hdd_dot11_mode = eHDD_DOT11_MODE_11n;
-			break;
-		case eHDD_DOT11_MODE_11ac:
-		case eHDD_DOT11_MODE_11ac_ONLY:
-			if (sme_is_feature_supported_by_fw(DOT11AC))
-				hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
-			else
-				hdd_dot11_mode = eHDD_DOT11_MODE_11n;
-			break;
-		case eHDD_DOT11_MODE_11n:
-		case eHDD_DOT11_MODE_11n_ONLY:
-			hdd_dot11_mode = eHDD_DOT11_MODE_11n;
-			break;
-		default:
-			hdd_dot11_mode = iniDot11Mode;
-			break;
-		}
-		ch_info->channel_width = ch_params->ch_width;
-		ch_info->phy_mode =
-			hdd_cfg_xlate_to_csr_phy_mode(hdd_dot11_mode);
-		ch_info->channel = operationChannel;
-		ch_info->cb_mode = ch_params->ch_width;
-		hdd_debug("ch_info width %d, phymode %d channel %d",
-			 ch_info->channel_width, ch_info->phy_mode,
-			 ch_info->channel);
-	}
+	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
+		hdd_mon_select_cbmode(adapter, operationChannel, ch_params);
 }
 
 /**
@@ -22013,6 +22030,7 @@
 	return 0;
 }
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 /**
  * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
  * @wiphy: Handle to struct wiphy to get handle to module context.
@@ -22117,6 +22135,7 @@
 	cds_ssr_unprotect(__func__);
 	return ret;
 }
+#endif
 
 /**
  * wlan_hdd_clear_link_layer_stats() - clear link layer stats
@@ -22677,7 +22696,9 @@
 #ifdef CHANNEL_SWITCH_SUPPORTED
 	.channel_switch = wlan_hdd_cfg80211_channel_switch,
 #endif
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 	.set_monitor_channel = wlan_hdd_cfg80211_set_mon_ch,
+#endif
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
 	defined(CFG80211_ABORT_SCAN)
 	.abort_scan = wlan_hdd_cfg80211_abort_scan,
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 09256a1..bf78a78 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -2133,6 +2133,7 @@
 	memset(dev->broadcast, 0xFF, ETH_ALEN);
 }
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 /**
  * __hdd__mon_open() - HDD Open function
  * @dev: Pointer to net_device structure
@@ -2201,6 +2202,7 @@
 
 	return ret;
 }
+#endif
 
 static QDF_STATUS
 wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
@@ -3525,6 +3527,7 @@
 #endif
 };
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 /* Monitor mode net_device_ops, doesnot Tx and most of operations. */
 static const struct net_device_ops wlan_mon_drv_ops = {
 	.ndo_open = hdd_mon_open,
@@ -3544,6 +3547,12 @@
 	else
 		dev->netdev_ops = &wlan_drv_ops;
 }
+#else
+void hdd_set_station_ops(struct net_device *dev)
+{
+	dev->netdev_ops = &wlan_drv_ops;
+}
+#endif
 
 /**
  * hdd_alloc_station_adapter() - allocate the station hdd adapter
@@ -5875,6 +5884,7 @@
 }
 #endif
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
 				 uint32_t bandwidth)
 {
@@ -5952,6 +5962,7 @@
 	adapter->mon_bandwidth = bandwidth;
 	return qdf_status_to_os_return(status);
 }
+#endif
 
 #ifdef MSM_PLATFORM
 /**
@@ -12447,6 +12458,32 @@
 	return param_set_copystring(kmessage, kp);
 }
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
+static bool is_monitor_mode_supported(void)
+{
+	return true;
+}
+#else
+static bool is_monitor_mode_supported(void)
+{
+	pr_err("Monitor mode not supported!");
+	return false;
+}
+#endif
+
+#ifdef WLAN_FEATURE_EPPING
+static bool is_epping_mode_supported(void)
+{
+	return true;
+}
+#else
+static bool is_epping_mode_supported(void)
+{
+	pr_err("Epping mode not supported!");
+	return false;
+}
+#endif
+
 /**
  * is_con_mode_valid() check con mode is valid or not
  * @mode: global con mode
@@ -12457,8 +12494,10 @@
 {
 	switch (mode) {
 	case QDF_GLOBAL_MONITOR_MODE:
-	case QDF_GLOBAL_FTM_MODE:
+		return is_monitor_mode_supported();
 	case QDF_GLOBAL_EPPING_MODE:
+		return is_epping_mode_supported();
+	case QDF_GLOBAL_FTM_MODE:
 	case QDF_GLOBAL_MISSION_MODE:
 		return true;
 	default:
@@ -12752,6 +12791,7 @@
 	return ret;
 }
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 static int con_mode_handler_monitor(const char *kmessage,
 				    const struct kernel_param *kp)
 {
@@ -12769,6 +12809,7 @@
 
 	return ret;
 }
+#endif
 
 /**
  * hdd_get_conparam() - driver exit point
@@ -14026,10 +14067,12 @@
 	.get = param_get_int,
 };
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 static const struct kernel_param_ops con_mode_monitor_ops = {
 	.set = con_mode_handler_monitor,
 	.get = param_get_int,
 };
+#endif
 
 static const struct kernel_param_ops fwpath_ops = {
 	.set = fwpath_changed_handler,
@@ -14042,8 +14085,10 @@
 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 module_param_cb(con_mode_monitor, &con_mode_monitor_ops, &con_mode_monitor,
 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+#endif
 
 module_param_cb(fwpath, &fwpath_ops, &fwpath,
 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index 9fda667..cfa3c66 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -1304,6 +1304,7 @@
 	return status;
 }
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 /**
  * hdd_mon_rx_packet_cbk() - Receive callback registered with OL layer.
  * @context: [in] pointer to qdf context
@@ -1379,6 +1380,7 @@
 
 	return QDF_STATUS_SUCCESS;
 }
+#endif
 
 /**
  * hdd_get_peer_idx() - Get the idx for given address in peer table
@@ -2338,6 +2340,7 @@
 		adapter->history_index = 0;
 }
 
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 /**
  * hdd_set_mon_rx_cb() - Set Monitor mode Rx callback
  * @dev:        Pointer to net_device structure
@@ -2381,6 +2384,7 @@
 	ret = qdf_status_to_os_return(qdf_status);
 	return ret;
 }
+#endif
 
 /**
  * hdd_send_rps_ind() - send rps indication to daemon
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index b246aec..9b182dc 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -10126,11 +10126,12 @@
 	 0, "dump_dp_trace"}
 	,
 #endif
+#ifdef FEATURE_MONITOR_MODE_SUPPORT
 	{WE_SET_MON_MODE_CHAN,
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
 	 0, "setMonChan"}
 	,
-
+#endif
 	{WE_GET_ROAM_SYNCH_DELAY,
 	 0,
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,