From 30f54666ae15128f26fbad787a35253885a10513 Mon Sep 17 00:00:00 2001
From: Ramya Gnanasekar <rgnanase@codeaurora.org>
Date: Fri, 25 Dec 2020 16:11:06 +0530
Subject: [PATCH] ath11k: Disable rx_header tlv for 2K SKB

On low memory platform hdr_status in hal_rx_desc is not subscribed to
get a savings of 128bytes in skb. This is required to reduce the skb
size from 4K to 2K. Use HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message
to unsubscribe rx_pkt_header tlv for rxdma ring.

Signed-off-by: Ramya Gnanasekar <rgnanase@codeaurora.org>

--- a/drivers/net/wireless/ath/ath11k/debugfs.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -1224,6 +1224,7 @@ static ssize_t ath11k_write_extd_rx_stat
 	}
 
 	ar->debug.rx_filter = tlv_filter.rx_filter;
+	tlv_filter.offset_valid = false;
 
 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
@@ -1732,6 +1733,7 @@ static ssize_t ath11k_write_pktlog_filte
 	}
 
 	/* Clear rx filter set for monitor mode and rx status */
+	tlv_filter.offset_valid = false;
 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
--- a/drivers/net/wireless/ath/ath11k/dp.h
+++ b/drivers/net/wireless/ath/ath11k/dp.h
@@ -224,7 +224,8 @@ struct ath11k_pdev_dp {
 #define DP_REO_CMD_RING_SIZE		128
 #define DP_REO_STATUS_RING_SIZE		2048
 #define DP_RXDMA_BUF_RING_SIZE		4096
-#define DP_RXDMA_REFILL_RING_SIZE	2048
+#define DP_RXDMA_REFILL_RING_SIZE	ATH11K_DP_RXDMA_REFILL_RING_SIZE
+#define DP_RXDMA_NSS_REFILL_RING_SIZE	ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE
 #define DP_RXDMA_ERR_DST_RING_SIZE	1024
 #define DP_RXDMA_MON_STATUS_RING_SIZE	ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE
 #define DP_RXDMA_MONITOR_BUF_RING_SIZE	ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE
@@ -646,7 +647,7 @@ enum htt_stats_internal_ppdu_frametype {
  *
  *    |31       26|25|24|23            16|15             8|7             0|
  *    |-----------------+----------------+----------------+---------------|
- *    |   rsvd1   |PS|SS|     ring_id    |     pdev_id    |    msg_type   |
+ *    |   rsvd1|OV|PS|SS|     ring_id    |     pdev_id    |    msg_type   |
  *    |-------------------------------------------------------------------|
  *    |              rsvd2               |           ring_buffer_size     |
  *    |-------------------------------------------------------------------|
@@ -660,6 +661,14 @@ enum htt_stats_internal_ppdu_frametype {
  *    |-------------------------------------------------------------------|
  *    |                         tlv_filter_in_flags                       |
  *    |-------------------------------------------------------------------|
+ *    |         rx_header_offset         |       rx_packet_offset         |
+ *    |-------------------------------------------------------------------|
+ *    |       rx_mpdu_start_offset       |      rx_mpdu_end_offset        |
+ *    |-------------------------------------------------------------------|
+ *    |       rx_msdu_start_offset       |      rx_msdu_end_offset        |
+ *    |-------------------------------------------------------------------|
+ *    |              rsvd3               |      rx_attention_offset       |
+ *    |-------------------------------------------------------------------|
  * Where:
  *     PS = pkt_swap
  *     SS = status_swap
@@ -673,7 +682,10 @@ enum htt_stats_internal_ppdu_frametype {
  *                    More details can be got from enum htt_srng_ring_id
  *          b'24    - status_swap: 1 is to swap status TLV
  *          b'25    - pkt_swap:  1 is to swap packet TLV
- *          b'26:31 - rsvd1:  reserved for future use
+ *	    b'26    - rx_offset_valid (OV): flag to indicate rx offsets
+ *		      configuration fields are valid
+ *
+ *          b'27:31 - rsvd1:  reserved for future use
  * dword1 - b'0:16  - ring_buffer_size: size of bufferes referenced by rx ring,
  *                    in byte units.
  *                    Valid only for HW_TO_SW_RING and SW_TO_HW_RING
@@ -702,6 +714,42 @@ enum htt_stats_internal_ppdu_frametype {
  * dword6 - b'0:31 -  tlv_filter_in_flags:
  *                    Filter in Attention/MPDU/PPDU/Header/User tlvs
  *                    Refer to CFG_TLV_FILTER_IN_FLAG defs
+ * dword7 - b'0:15 -  rx_packet_offset: rx_packet_offset in byte units
+ *		      Valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ *		      A value of 0 will be considered as ignore this config.
+ *		      Refer to BUF_RING_CFG_1 defs within HW .h files,
+ *		      e.g. wmac_top_reg_seq_hwioreg.h
+ *	  - b'16:31 - rx_header_offset: rx_header_offset in byte units
+ *		      Valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ *		      A value of 0 will be considered as ignore this config.
+ *		      Refer to BUF_RING_CFG_1 defs within HW .h files,
+ *		      e.g. wmac_top_reg_seq_hwioreg.h
+ * dword8 - b'0:15 -  rx_mpdu_end_offset: rx_mpdu_end_offset in byte units
+ *	              Valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ *		      A value of 0 will be considered as ignore this config.
+ *		      Refer to BUF_RING_CFG_2 defs within HW .h files,
+ *		      e.g. wmac_top_reg_seq_hwioreg.h
+ *	  - b'16:31 - rx_mpdu_start_offset: rx_mpdu_start_offset in byte units
+ *		      Valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ *		      A value of 0 will be considered as ignore this config.
+ *		      Refer to BUF_RING_CFG_2 defs within HW .h files,
+ *		      e.g. wmac_top_reg_seq_hwioreg.h
+ * dword9 - b'0:15 -  rx_msdu_end_offset: rx_msdu_end_offset in byte units
+ *		      Valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ *		      A value of 0 will be considered as ignore this config.
+ *		      Refer to BUF_RING_CFG_3 defs within HW .h files,
+ *		      e.g. wmac_top_reg_seq_hwioreg.h
+ *	  - b'16:31 - rx_msdu_start_offset: rx_msdu_start_offset in byte units
+ *		      Valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ *		      A value of 0 will be considered as ignore this config.
+ *		      Refer to BUF_RING_CFG_3 defs within HW .h files,
+ *		      e.g. wmac_top_reg_seq_hwioreg.h
+ * dword10- b'0:15  - rx_attention_offset: rx_attention_offset in byte units
+ *		      Valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ *		      A value of 0 will be considered as ignore this config.
+ *		      Refer to BUF_RING_CFG_4 defs within HW .h files,
+ *		      e.g. wmac_top_reg_seq_hwioreg.h
+ *	  - b'16:31 - rsvd3 for future use
  */
 
 #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE	GENMASK(7, 0)
@@ -709,8 +757,16 @@ enum htt_stats_internal_ppdu_frametype {
 #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID	GENMASK(23, 16)
 #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS		BIT(24)
 #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS		BIT(25)
+#define HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID      BIT(26)
 
 #define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE	GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET      GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET      GENMASK(31, 16)
+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET    GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET  GENMASK(31, 16)
+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET    GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET  GENMASK(31, 16)
+#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET   GENMASK(15, 0)
 
 enum htt_rx_filter_tlv_flags {
 	HTT_RX_FILTER_TLV_FLAGS_MPDU_START		= BIT(0),
@@ -1014,6 +1070,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 {
 		HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \
 		HTT_RX_FILTER_TLV_FLAGS_ATTENTION)
 
+#define HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING \
+		(HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
+		HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \
+		HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \
+		HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \
+		HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \
+		HTT_RX_FILTER_TLV_FLAGS_ATTENTION)
+
 struct htt_rx_ring_selection_cfg_cmd {
 	u32 info0;
 	u32 info1;
@@ -1022,6 +1086,10 @@ struct htt_rx_ring_selection_cfg_cmd {
 	u32 pkt_type_en_flags2;
 	u32 pkt_type_en_flags3;
 	u32 rx_filter_tlv;
+	u32 rx_packet_offset;
+	u32 rx_mpdu_offset;
+	u32 rx_msdu_offset;
+	u32 rx_attn_offset;
 } __packed;
 
 struct htt_rx_ring_tlv_filter {
@@ -1030,6 +1098,14 @@ struct htt_rx_ring_tlv_filter {
 	u32 pkt_filter_flags1; /* MGMT */
 	u32 pkt_filter_flags2; /* CTRL */
 	u32 pkt_filter_flags3; /* DATA */
+	bool offset_valid;
+	u16 rx_packet_offset;
+	u16 rx_header_offset;
+	u16 rx_mpdu_end_offset;
+	u16 rx_mpdu_start_offset;
+	u16 rx_msdu_end_offset;
+	u16 rx_msdu_start_offset;
+	u16 rx_attn_offset;
 };
 
 /**
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -59,6 +59,12 @@ static bool ath11k_dp_rx_h_mpdu_start_fc
 	return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc);
 }
 
+static u16 ath11k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath11k_base *ab,
+						struct hal_rx_desc *desc)
+{
+	return ab->hw_params.hw_ops->rx_desc_get_mpdu_frame_ctl(desc);
+}
+
 static bool ath11k_dp_rx_h_mpdu_start_more_frags(struct ath11k_base *ab,
 						 struct sk_buff *skb)
 {
@@ -306,17 +312,46 @@ bool ath11k_dp_rx_h_attn_is_mcbc(struct
 }
 
 static bool ath11k_dp_rxdesc_mac_addr2_valid(struct ath11k_base *ab,
-                   struct hal_rx_desc *desc)
+					struct hal_rx_desc *desc)
 {
-   return ab->hw_params.hw_ops->rx_desc_mac_addr2_valid(desc);
+	return ab->hw_params.hw_ops->rx_desc_mac_addr2_valid(desc);
 }
 
 static u8* ath11k_dp_rxdesc_get_mpdu_start_addr2(struct ath11k_base *ab,
-                   struct hal_rx_desc *desc)
+					struct hal_rx_desc *desc)
 {
 	return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2;
 }
 
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+static void ath11k_dp_get_rx_header_offset(struct ath11k_base *ab,
+					   struct htt_rx_ring_tlv_filter *tlv_filter)
+{
+	ab->hw_params.hw_ops->rx_desc_get_offset(tlv_filter);
+}
+#endif
+
+static bool ath11k_dp_rx_desc_dot11_hdr_fields_valid(struct ath11k_base *ab,
+						     struct hal_rx_desc *desc)
+{
+	return ab->hw_params.hw_ops->rx_desc_dot11_hdr_fields_valid(desc);
+}
+
+static void ath11k_dp_rx_desc_get_dot11_hdr(struct ath11k_base *ab,
+					    struct hal_rx_desc *desc,
+					    struct ieee80211_hdr *hdr)
+{
+	ab->hw_params.hw_ops->rx_desc_get_dot11_hdr(desc, hdr);
+}
+
+static void ath11k_dp_rx_desc_get_crypto_header(struct ath11k_base *ab,
+						struct hal_rx_desc *desc,
+						u8 *crypto_hdr,
+						enum hal_encrypt_type enctype)
+{
+	ab->hw_params.hw_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype);
+}
+
 /* Returns number of Rx buffers replenished */
 int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
 			       struct dp_rxdma_ring *rx_ring,
@@ -2068,6 +2103,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a
 	return 0;
 }
 
+static void ath11k_get_dot11_hdr_from_rx_desc(struct ath11k *ar,
+					      struct sk_buff *msdu,
+					      struct ath11k_skb_rxcb *rxcb,
+					      struct ieee80211_rx_status *status,
+					      enum hal_encrypt_type enctype)
+{
+	struct hal_rx_desc *rx_desc = rxcb->rx_desc;
+	struct ath11k_base *ab = ar->ab;
+	size_t hdr_len, crypto_len;
+	struct ieee80211_hdr *hdr;
+	u16 fc, qos_ctl = 0;
+	u8 *crypto_hdr;
+
+	if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
+		crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype);
+		crypto_hdr = skb_push(msdu, crypto_len);
+		ath11k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype);
+	}
+
+	fc = ath11k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc);
+	hdr_len = ieee80211_hdrlen(fc);
+	skb_push(msdu, hdr_len);
+	hdr = (struct ieee80211_hdr *)msdu->data;
+	hdr->frame_control = fc;
+
+	/* Get wifi header from rx_desc */
+	ath11k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr);
+
+	if (rxcb->is_mcbc)
+		status->flag &= ~RX_FLAG_PN_VALIDATED;
+
+	/* Add QOS header */
+	if (ieee80211_is_data_qos(hdr->frame_control)) {
+		qos_ctl = rxcb->tid;
+		if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ab, rx_desc))
+			qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT;
+
+		/* TODO Add other QoS ctl fields when required */
+		memcpy(msdu->data + (hdr_len - IEEE80211_QOS_CTL_LEN),
+		       &qos_ctl, IEEE80211_QOS_CTL_LEN);
+	}
+}
+
 static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar,
 					 struct sk_buff *msdu,
 					 u8 *first_hdr,
@@ -2081,7 +2159,8 @@ static void ath11k_dp_rx_h_undecap_nwifi
 	u8 da[ETH_ALEN];
 	u8 sa[ETH_ALEN];
 	u16 qos_ctl = 0;
-	u8 *qos;
+	u8 *qos, *crypto_hdr;
+	bool add_qos_ctrl = false;
 
 	/* copy SA & DA and pull decapped header */
 	hdr = (struct ieee80211_hdr *)msdu->data;
@@ -2090,7 +2169,7 @@ static void ath11k_dp_rx_h_undecap_nwifi
 	ether_addr_copy(sa, ieee80211_get_SA(hdr));
 	skb_pull(msdu, ieee80211_hdrlen(hdr->frame_control));
 
-	if (rxcb->is_first_msdu) {
+	if (rxcb->is_first_msdu && first_hdr) {
 		/* original 802.11 header is valid for the first msdu
 		 * hence we can reuse the same header
 		 */
@@ -2120,16 +2199,23 @@ static void ath11k_dp_rx_h_undecap_nwifi
 
 		/* copy decap header before overwriting for reuse below */
 		memcpy(decap_hdr, (uint8_t *)hdr, hdr_len);
+		add_qos_ctrl = true;
 	}
 
 	if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
-		memcpy(skb_push(msdu,
-				ath11k_dp_rx_crypto_param_len(ar, enctype)),
-		       (void *)hdr + hdr_len,
-		       ath11k_dp_rx_crypto_param_len(ar, enctype));
+		if (first_hdr) {
+			memcpy(skb_push(msdu,
+					ath11k_dp_rx_crypto_param_len(ar, enctype)),
+					(void *)hdr + hdr_len,
+					ath11k_dp_rx_crypto_param_len(ar, enctype));
+		} else {
+			crypto_hdr = skb_push(msdu, ath11k_dp_rx_crypto_param_len(ar, enctype));
+			ath11k_dp_rx_desc_get_crypto_header(ar->ab,
+							    rxcb->rx_desc, crypto_hdr, enctype);
+		}
 	}
 
-	if (!rxcb->is_first_msdu) {
+	if (!rxcb->is_first_msdu || add_qos_ctrl) {
 		memcpy(skb_push(msdu,
 				IEEE80211_QOS_CTL_LEN), &qos_ctl,
 				IEEE80211_QOS_CTL_LEN);
@@ -2245,6 +2331,20 @@ static void ath11k_dp_rx_h_undecap_eth(s
 	u8 da[ETH_ALEN];
 	u8 sa[ETH_ALEN];
 	void *rfc1042;
+	struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
+	struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}};
+
+	if (!first_hdr) {
+		eth = (struct ethhdr *)msdu->data;
+		ether_addr_copy(da, eth->h_dest);
+		ether_addr_copy(sa, eth->h_source);
+		rfc.snap_type = eth->h_proto;
+		skb_pull(msdu, sizeof(struct ethhdr));
+		memcpy(skb_push(msdu, sizeof(struct ath11k_dp_rfc1042_hdr)), &rfc,
+		       sizeof(struct ath11k_dp_rfc1042_hdr));
+		ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype);
+		goto exit;
+	}
 
 	rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype);
 	if (WARN_ON_ONCE(!rfc1042))
@@ -2273,6 +2373,7 @@ static void ath11k_dp_rx_h_undecap_eth(s
 
 	memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
 
+exit:
 	/* original 802.11 header has a different DA and in
 	 * case of 4addr it may also have different SA
 	 */
@@ -2291,6 +2392,7 @@ static void ath11k_dp_rx_h_undecap_snap(
 	size_t hdr_len;
 	u8 l3_pad_bytes;
 	struct hal_rx_desc *rx_desc;
+	struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
 
 	/* Delivered decapped frame:
 	 * [amsdu header] <-- replaced with 802.11 hdr
@@ -2304,6 +2406,11 @@ static void ath11k_dp_rx_h_undecap_snap(
 	skb_put(msdu, l3_pad_bytes);
 	skb_pull(msdu, sizeof(struct ath11k_dp_amsdu_subframe_hdr) + l3_pad_bytes);
 
+	if (!first_hdr) {
+		ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype);
+		return;
+	}
+
 	hdr = (struct ieee80211_hdr *)first_hdr;
 	hdr_len = ieee80211_hdrlen(hdr->frame_control);
 
@@ -2671,6 +2778,20 @@ static int ath11k_dp_rx_process_msdu(str
 		goto free_out;
 	}
 
+	hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc);
+	/* wifi hdr fields validation for 512M::
+	 * Mcast packets in ethernet frame mode
+	 * will need wifi hdr in msdu to validate PN.
+	 * Header will be added in undecap routine.
+	 * Validation on wifi hdr fields from rx_desc.
+	 */
+	if (!hdr_status && ath11k_dp_rx_h_attn_is_mcbc(ab, rx_desc) &&
+	    !ath11k_dp_rx_desc_dot11_hdr_fields_valid(ab, rx_desc)) {
+		ath11k_warn(ab, "One or more invalid dot11 header fields\n");
+		ret = -EIO;
+		goto free_out;
+	}
+
 	rxcb = ATH11K_SKB_RXCB(msdu);
 	rxcb->rx_desc = rx_desc;
 	msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ab, rx_desc);
@@ -2683,8 +2804,9 @@ static int ath11k_dp_rx_process_msdu(str
 			hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc);
 			ret = -EINVAL;
 			ath11k_warn(ab, "invalid msdu len %u\n", msdu_len);
-			ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
-					sizeof(struct ieee80211_hdr));
+			if (hdr_status)
+				ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
+						sizeof(struct ieee80211_hdr));
 			ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
 					sizeof(struct hal_rx_desc));
 			goto free_out;
@@ -3649,6 +3771,7 @@ static int ath11k_dp_rx_h_verify_tkip_mi
 
 	hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz);
 	hdr_len = ieee80211_hdrlen(hdr->frame_control);
+
 	head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN;
 	tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN;
 
@@ -3928,8 +4051,8 @@ static void ath11k_dp_rx_h_sort_frags(st
 
 static u64 ath11k_dp_rx_h_get_pn(struct ath11k *ar, struct sk_buff *skb)
 {
-	struct ieee80211_hdr *hdr;
 	u64 pn = 0;
+	struct ieee80211_hdr *hdr;
 	u8 *ehdr;
 	u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;
 
@@ -4146,8 +4269,9 @@ ath11k_dp_process_rx_err_buf(struct ath1
 	if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) {
 		hdr_status = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc);
 		ath11k_warn(ar->ab, "invalid msdu leng %u", msdu_len);
-		ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
-				sizeof(struct ieee80211_hdr));
+		if (hdr_status)
+			ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
+					sizeof(struct ieee80211_hdr));
 		ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
 				sizeof(struct hal_rx_desc));
 		dev_kfree_skb_any(msdu);
@@ -4770,6 +4894,47 @@ void ath11k_dp_rx_pdev_free(struct ath11
 	ath11k_dp_rxdma_pdev_buf_free(ar);
 }
 
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar)
+{
+	struct ath11k_pdev_dp *dp = &ar->dp;
+	struct htt_rx_ring_tlv_filter tlv_filter = {0};
+	u32 ring_id;
+	int ret;
+	u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;
+
+	ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id;
+
+	tlv_filter.rx_filter = HTT_RX_RXDMA_FILTER_TLV_FLAGS_BUF_RING;
+	tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR;
+	tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST |
+					HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST;
+	tlv_filter.offset_valid = true;
+	tlv_filter.rx_packet_offset = hal_rx_desc_sz;
+	tlv_filter.rx_header_offset = 0;
+
+	ath11k_dp_get_rx_header_offset(ar->ab, &tlv_filter);
+
+	if (!ar->ab->nss.enabled)
+		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id,
+						       HAL_RXDMA_BUF,
+						       DP_RXDMA_REFILL_RING_SIZE,
+						       &tlv_filter);
+	else
+		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id,
+						       HAL_RXDMA_BUF,
+						       DP_RXDMA_NSS_REFILL_RING_SIZE,
+						       &tlv_filter);
+
+	return ret;
+}
+#else
+static int ath11k_dp_rxdma_ring_sel_config(struct ath11k *ar)
+{
+	return 0;
+}
+#endif
+
 int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id)
 {
 	struct ath11k *ar = ab->pdevs[mac_id].ar;
@@ -4863,6 +5028,12 @@ config_refill_ring:
 		}
 	}
 
+	ret = ath11k_dp_rxdma_ring_sel_config(ar);
+	if (ret) {
+		ath11k_warn(ab, "failed to setup rxdma ring selection config\n");
+		return ret;
+	}
+
 	return 0;
 }
 
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -1112,6 +1112,8 @@ int ath11k_dp_tx_htt_rx_filter_setup(str
 				 !!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP));
 	cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS,
 				 !!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP));
+	cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID,
+				tlv_filter->offset_valid);
 
 	cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE,
 				rx_buf_size);
@@ -1121,6 +1123,26 @@ int ath11k_dp_tx_htt_rx_filter_setup(str
 	cmd->pkt_type_en_flags3 = tlv_filter->pkt_filter_flags3;
 	cmd->rx_filter_tlv = tlv_filter->rx_filter;
 
+	if (tlv_filter->offset_valid) {
+		cmd->rx_packet_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET,
+						   tlv_filter->rx_packet_offset);
+		cmd->rx_packet_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET,
+						    tlv_filter->rx_header_offset);
+
+		cmd->rx_mpdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET,
+						 tlv_filter->rx_mpdu_end_offset);
+		cmd->rx_mpdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET,
+						  tlv_filter->rx_mpdu_start_offset);
+
+		cmd->rx_msdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET,
+						 tlv_filter->rx_msdu_end_offset);
+		cmd->rx_msdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET,
+						  tlv_filter->rx_msdu_start_offset);
+
+		cmd->rx_attn_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET,
+						 tlv_filter->rx_attn_offset);
+	}
+
 	ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb);
 	if (ret)
 		goto err_free;
@@ -1193,6 +1215,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c
 	}
 
 	ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id;
+	tlv_filter.offset_valid = false;
 
 	if (!reset) {
 		tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING;
--- a/drivers/net/wireless/ath/ath11k/hw.c
+++ b/drivers/net/wireless/ath/ath11k/hw.c
@@ -194,7 +194,11 @@ static u8 ath11k_hw_ipq8074_rx_desc_get_
 
 static u8 *ath11k_hw_ipq8074_rx_desc_get_hdr_status(struct hal_rx_desc *desc)
 {
+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M
 	return desc->u.ipq8074.hdr_status;
+#else
+	return NULL;
+#endif
 }
 
 static bool ath11k_hw_ipq8074_rx_desc_encrypt_valid(struct hal_rx_desc *desc)
@@ -367,6 +371,123 @@ u32 ath11k_hw_ipq8074_rx_desc_get_hal_mp
 			 __le32_to_cpu(mpdu_info->u.ipq8074.info1));
 }
 
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+static void ath11k_hw_ipq8074_rx_desc_get_offset(struct htt_rx_ring_tlv_filter *tlv_filter)
+{
+	tlv_filter->rx_mpdu_end_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_ipq8074, mpdu_end_tag));
+	tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_ipq8074, mpdu_start_tag));
+	tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_ipq8074, msdu_end_tag));
+	tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_ipq8074, msdu_start_tag));
+	tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_ipq8074, rx_attn_tag));
+}
+#endif
+
+static u16 ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
+{
+	return __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl);
+}
+
+static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
+{
+	return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) &
+	       RX_MPDU_START_INFO1_MAC_ADDR2_VALID;
+}
+
+static u8* ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
+{
+	return desc->u.ipq8074.mpdu_start.addr2;
+}
+
+static bool ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc)
+{
+	if ((ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(desc) &&
+	     ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid(desc) &&
+	     __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) &
+			   RX_MPDU_START_INFO1_MAC_ADDR1_VALID &&
+	     ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(desc) &&
+	     __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) &
+			   RX_MPDU_START_INFO1_MAC_ADDR3_VALID &&
+	     FIELD_GET((RX_MPDU_START_INFO1_MPDU_DUR_VALID),
+			__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)))) {
+		return true;
+	}
+	return false;
+}
+
+static void ath11k_hw_ipq8074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc,
+						    struct ieee80211_hdr *hdr)
+{
+	hdr->frame_control = __le16_to_cpu(desc->u.ipq8074.mpdu_start.frame_ctrl);
+	hdr->duration_id = __le16_to_cpu(desc->u.ipq8074.mpdu_start.duration);
+	ether_addr_copy(hdr->addr1, desc->u.ipq8074.mpdu_start.addr1);
+	ether_addr_copy(hdr->addr2, desc->u.ipq8074.mpdu_start.addr2);
+	ether_addr_copy(hdr->addr3, desc->u.ipq8074.mpdu_start.addr3);
+	if (__le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) &
+			RX_MPDU_START_INFO1_MAC_ADDR4_VALID) {
+		ether_addr_copy(hdr->addr4, desc->u.ipq8074.mpdu_start.addr4);
+	}
+	hdr->seq_ctrl = __le16_to_cpu(desc->u.ipq8074.mpdu_start.seq_ctrl);
+}
+
+static void ath11k_hw_ipq8074_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
+						     u8 *crypto_hdr,
+						     enum hal_encrypt_type enctype)
+{
+	unsigned int key_id;
+
+	switch (enctype) {
+	case HAL_ENCRYPT_TYPE_OPEN:
+		return;
+	case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:
+	case HAL_ENCRYPT_TYPE_TKIP_MIC:
+		crypto_hdr[0] =
+			HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[0]);
+		crypto_hdr[1] = 0;
+		crypto_hdr[2] =
+			HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[0]);
+		break;
+	case HAL_ENCRYPT_TYPE_CCMP_128:
+	case HAL_ENCRYPT_TYPE_CCMP_256:
+	case HAL_ENCRYPT_TYPE_GCMP_128:
+	case HAL_ENCRYPT_TYPE_AES_GCMP_256:
+		crypto_hdr[0] =
+			HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[0]);
+		crypto_hdr[1] =
+			HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[0]);
+		crypto_hdr[2] = 0;
+		break;
+	case HAL_ENCRYPT_TYPE_WEP_40:
+	case HAL_ENCRYPT_TYPE_WEP_104:
+	case HAL_ENCRYPT_TYPE_WEP_128:
+	case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:
+	case HAL_ENCRYPT_TYPE_WAPI:
+		return;
+	}
+	key_id        = FIELD_GET(RX_MPDU_START_INFO5_KEY_ID,
+				  __le32_to_cpu(desc->u.ipq8074.mpdu_start.info5));
+	crypto_hdr[3] = 0x20 | (key_id << 6);
+	crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.ipq8074.mpdu_start.pn[0]);
+	crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.ipq8074.mpdu_start.pn[0]);
+	crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.ipq8074.mpdu_start.pn[1]);
+	crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.ipq8074.mpdu_start.pn[1]);
+}
+
+static bool ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
+{
+        return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) &
+	       RX_MPDU_START_INFO11_MAC_ADDR2_VALID;
+}
+
+static u8* ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
+{
+        return desc->u.qcn9074.mpdu_start.addr2;
+}
+
 static bool ath11k_hw_qcn9074_rx_desc_get_first_msdu(struct hal_rx_desc *desc)
 {
 	return !!FIELD_GET(RX_MSDU_END_INFO4_FIRST_MSDU,
@@ -387,7 +508,11 @@ static u8 ath11k_hw_qcn9074_rx_desc_get_
 
 static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc)
 {
-	return desc->u.qcn9074.hdr_status;
+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M
+	return desc->u.ipq8074.hdr_status;
+#else
+	return NULL;
+#endif
 }
 
 static bool ath11k_hw_qcn9074_rx_desc_encrypt_valid(struct hal_rx_desc *desc)
@@ -534,17 +659,6 @@ static bool ath11k_hw_ipq8074_rx_desc_ge
 
 }
 
-static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
-{
-	return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) &
-	       RX_MPDU_START_INFO1_MAC_ADDR2_VALID;
-}
-
-static u8* ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
-{
-	return desc->u.ipq8074.mpdu_start.addr2;
-}
-
 static void ath11k_hw_ipq5018_set_rx_fragmentation_dst_ring(struct ath11k_base *ab)
 {
 	u8 frag_dst_ring = HAL_SRNG_RING_ID_REO2SW1;
@@ -582,6 +696,97 @@ u32 ath11k_hw_qcn9074_rx_desc_get_hal_mp
 			 __le32_to_cpu(mpdu_info->u.qcn9074.info1));
 }
 
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+static void ath11k_hw_qcn9074_rx_desc_get_offset(struct htt_rx_ring_tlv_filter *tlv_filter)
+{
+	tlv_filter->rx_mpdu_end_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_qcn9074, mpdu_end_tag));
+	tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_qcn9074, mpdu_start_tag));
+	tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_qcn9074, msdu_end_tag));
+	tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_qcn9074, msdu_start_tag));
+	tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof
+			(struct hal_rx_desc_qcn9074, rx_attn_tag));
+}
+#endif
+
+static u16 ath11k_hw_qcn9074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
+{
+	return __le16_to_cpu(desc->u.qcn9074.mpdu_start.frame_ctrl);
+}
+
+static bool ath11k_hw_qcn9074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc)
+{
+	if ((ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld(desc) &&
+	     ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid(desc) &&
+	     (__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) &
+			     RX_MPDU_START_INFO11_MAC_ADDR1_VALID) &&
+	     ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(desc) &&
+	     (__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) &
+			    RX_MPDU_START_INFO11_MAC_ADDR3_VALID) &&
+	     FIELD_GET((RX_MPDU_START_INFO11_MPDU_DUR_VALID),
+			__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11)))) {
+		return true;
+	}
+	return false;
+}
+
+static void ath11k_hw_qcn9074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc,
+						    struct ieee80211_hdr *hdr)
+{
+	hdr->frame_control = __le16_to_cpu(desc->u.qcn9074.mpdu_start.frame_ctrl);
+	hdr->duration_id = __le16_to_cpu(desc->u.qcn9074.mpdu_start.duration);
+	ether_addr_copy(hdr->addr1, desc->u.qcn9074.mpdu_start.addr1);
+	ether_addr_copy(hdr->addr2, desc->u.qcn9074.mpdu_start.addr2);
+	ether_addr_copy(hdr->addr3, desc->u.qcn9074.mpdu_start.addr3);
+	if (__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) &
+			  RX_MPDU_START_INFO11_MAC_ADDR4_VALID) {
+		ether_addr_copy(hdr->addr4, desc->u.qcn9074.mpdu_start.addr4);
+	}
+	hdr->seq_ctrl = __le16_to_cpu(desc->u.qcn9074.mpdu_start.seq_ctrl);
+}
+
+static void ath11k_hw_qcn9074_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
+						     u8 *crypto_hdr,
+						     enum hal_encrypt_type enctype)
+{
+	unsigned int key_id;
+
+	switch (enctype) {
+	case HAL_ENCRYPT_TYPE_OPEN:
+		return;
+	case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:
+	case HAL_ENCRYPT_TYPE_TKIP_MIC:
+		crypto_hdr[0] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9074.mpdu_start.pn[0]);
+		crypto_hdr[1] = 0;
+		crypto_hdr[2] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9074.mpdu_start.pn[0]);
+		break;
+	case HAL_ENCRYPT_TYPE_CCMP_128:
+	case HAL_ENCRYPT_TYPE_CCMP_256:
+	case HAL_ENCRYPT_TYPE_GCMP_128:
+	case HAL_ENCRYPT_TYPE_AES_GCMP_256:
+		crypto_hdr[0] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9074.mpdu_start.pn[0]);
+		crypto_hdr[1] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9074.mpdu_start.pn[0]);
+		crypto_hdr[2] = 0;
+		break;
+	case HAL_ENCRYPT_TYPE_WEP_40:
+	case HAL_ENCRYPT_TYPE_WEP_104:
+	case HAL_ENCRYPT_TYPE_WEP_128:
+	case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:
+	case HAL_ENCRYPT_TYPE_WAPI:
+		return;
+	}
+	key_id        = FIELD_GET(RX_MPDU_START_INFO12_KEY_ID,
+				  __le32_to_cpu(desc->u.qcn9074.mpdu_start.info12));
+	crypto_hdr[3] = 0x20 | (key_id << 6);
+	crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9074.mpdu_start.pn[0]);
+	crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9074.mpdu_start.pn[0]);
+	crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9074.mpdu_start.pn[1]);
+	crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9074.mpdu_start.pn[1]);
+}
+
 static u32 ath11k_get_reo_dest_remap_config_default(void)
 {
 	u32 ring_hash_map;
@@ -662,6 +867,13 @@ const struct ath11k_hw_ops ipq8074_ops =
 	.get_reo_dest_remap_config = ath11k_get_reo_dest_remap_config_default,
 	.rx_desc_get_hal_mpdu_peerid = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_peerid,
 	.rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len,
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+	.rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset,
+#endif
+	.rx_desc_get_mpdu_frame_ctl = ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl,
+	.rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid,
+	.rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr,
+	.rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr,
 };
 
 const struct ath11k_hw_ops ipq6018_ops = {
@@ -703,6 +915,13 @@ const struct ath11k_hw_ops ipq6018_ops =
 	.get_reo_dest_remap_config = ath11k_get_reo_dest_remap_config_default,
 	.rx_desc_get_hal_mpdu_peerid = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_peerid,
 	.rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len,
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+	.rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset,
+#endif
+	.rx_desc_get_mpdu_frame_ctl = ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl,
+	.rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid,
+	.rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr,
+	.rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr,
 };
 
 const struct ath11k_hw_ops qca6390_ops = {
@@ -741,6 +960,13 @@ const struct ath11k_hw_ops qca6390_ops =
 	.get_reo_dest_remap_config = ath11k_get_reo_dest_remap_config_default,
 	.rx_desc_get_hal_mpdu_peerid = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_peerid,
 	.rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len,
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+	.rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset,
+#endif
+	.rx_desc_get_mpdu_frame_ctl = ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl,
+	.rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid,
+	.rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr,
+	.rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr,
 	//TODO
 	/*	.rx_desc_get_da_mcbc,
 		.rx_desc_mac_addr2_valid,
@@ -753,6 +979,9 @@ const struct ath11k_hw_ops qcn9074_ops =
 	.wmi_init_config = ath11k_init_wmi_config_ipq8074,
 	.mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074,
 	.mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074,
+	.rx_desc_get_da_mcbc = ath11k_hw_ipq8074_rx_desc_get_da_mcbc,
+	.rx_desc_mac_addr2_valid = ath11k_hw_qcn9074_rx_desc_mac_addr2_valid,
+	.rx_desc_mpdu_start_addr2 = ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2,
 	.tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable,
 	.rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu,
 	.rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu,
@@ -784,6 +1013,13 @@ const struct ath11k_hw_ops qcn9074_ops =
 	.get_reo_dest_remap_config = ath11k_get_reo_dest_remap_config_default,
 	.rx_desc_get_hal_mpdu_peerid = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_peerid,
 	.rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len,
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+	.rx_desc_get_offset = ath11k_hw_qcn9074_rx_desc_get_offset,
+#endif
+	.rx_desc_get_mpdu_frame_ctl = ath11k_hw_qcn9074_rx_desc_get_mpdu_frame_ctl,
+	.rx_desc_dot11_hdr_fields_valid = ath11k_hw_qcn9074_rx_desc_dot11_hdr_fields_valid,
+	.rx_desc_get_dot11_hdr = ath11k_hw_qcn9074_rx_desc_get_dot11_hdr,
+	.rx_desc_get_crypto_header = ath11k_hw_qcn9074_rx_desc_get_crypto_hdr,
 };
 
 /* IPQ5018 hw ops is similar to QCN9074 except for the dest ring remap */
@@ -793,8 +1029,8 @@ const struct ath11k_hw_ops ipq5018_ops =
 	.mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074,
 	.mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074,
 	.rx_desc_get_da_mcbc = ath11k_hw_ipq8074_rx_desc_get_da_mcbc,
-	.rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
-	.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
+	.rx_desc_mac_addr2_valid = ath11k_hw_qcn9074_rx_desc_mac_addr2_valid,
+	.rx_desc_mpdu_start_addr2 = ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2,
 	.tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable,
 	.rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu,
 	.rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu,
@@ -826,6 +1062,13 @@ const struct ath11k_hw_ops ipq5018_ops =
 	.rx_desc_get_hal_mpdu_peerid = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_peerid,
 	.rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len,
 	.get_reo_dest_remap_config = ath11k_get_reo_dest_remap_config_5018,
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+	.rx_desc_get_offset = ath11k_hw_qcn9074_rx_desc_get_offset,
+#endif
+	.rx_desc_get_mpdu_frame_ctl = ath11k_hw_qcn9074_rx_desc_get_mpdu_frame_ctl,
+	.rx_desc_dot11_hdr_fields_valid = ath11k_hw_qcn9074_rx_desc_dot11_hdr_fields_valid,
+	.rx_desc_get_dot11_hdr = ath11k_hw_qcn9074_rx_desc_get_dot11_hdr,
+	.rx_desc_get_crypto_header = ath11k_hw_qcn9074_rx_desc_get_crypto_hdr,
  };
 
 const struct ath11k_hw_ops qcn6122_ops = {
@@ -834,8 +1077,8 @@ const struct ath11k_hw_ops qcn6122_ops =
 	.mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074,
 	.mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074,
 	.rx_desc_get_da_mcbc = ath11k_hw_ipq8074_rx_desc_get_da_mcbc,
-	.rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
-	.rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
+	.rx_desc_mac_addr2_valid = ath11k_hw_qcn9074_rx_desc_mac_addr2_valid,
+	.rx_desc_mpdu_start_addr2 = ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2,
 	.tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable,
 	.rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu,
 	.rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu,
@@ -867,7 +1110,13 @@ const struct ath11k_hw_ops qcn6122_ops =
 	.rx_desc_get_hal_mpdu_peerid = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_peerid,
 	.rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len,
 	.get_reo_dest_remap_config = ath11k_get_reo_dest_remap_config_5018,
-	.rx_process_mon_rings = ath11k_dp_rx_process_mon_rings_ipq8074,
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+	.rx_desc_get_offset = ath11k_hw_qcn9074_rx_desc_get_offset,
+#endif
+	.rx_desc_get_mpdu_frame_ctl = ath11k_hw_qcn9074_rx_desc_get_mpdu_frame_ctl,
+	.rx_desc_dot11_hdr_fields_valid = ath11k_hw_qcn9074_rx_desc_dot11_hdr_fields_valid,
+	.rx_desc_get_dot11_hdr = ath11k_hw_qcn9074_rx_desc_get_dot11_hdr,
+	.rx_desc_get_crypto_header = ath11k_hw_qcn9074_rx_desc_get_crypto_hdr,
 };
 
 #define ATH11K_TX_RING_MASK_0 0x1
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -20,6 +20,11 @@
 #define ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE	512
 #define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE	128
 #define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE	128
+#define ATH11K_DP_RXDMA_REFILL_RING_SIZE	2048
+/* 256b desc TLV + 4b(rounded) Pad + 30byte max nwifi header +
+ * 18byte mesh hdr + 8byte snap + 1500 eth payload
+ */
+#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE	1816
 #else
 /* Num VDEVS per radio */
 #define TARGET_NUM_VDEVS	(ab->num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs)
@@ -31,6 +36,8 @@
 #define ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE	1024
 #define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE	4096
 #define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE	2048
+#define ATH11K_DP_RXDMA_REFILL_RING_SIZE	2048
+#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE	2048
 #endif
 
 /* Num of peers for Single Radio mode */
@@ -128,6 +135,8 @@ struct hal_rx_mpdu_info;
 struct hal_rx_desc;
 struct hal_tcl_data_cmd;
 struct napi_struct;
+struct htt_rx_ring_tlv_filter;
+enum hal_encrypt_type;
 
 struct ath11k_hw_ring_mask {
 	u8 tx[ATH11K_EXT_IRQ_GRP_NUM_MAX];
@@ -238,6 +247,16 @@ struct ath11k_hw_ops {
 	u32 (*get_reo_dest_remap_config)(void);
 	u16 (*rx_desc_get_hal_mpdu_peerid) (struct hal_rx_mpdu_info *mpdu_info);
 	u32 (*rx_desc_get_hal_mpdu_len) (struct hal_rx_mpdu_info *mpdu_info);
+#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M
+	void (*rx_desc_get_offset)(struct htt_rx_ring_tlv_filter *tlv_filter);
+#endif
+	u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc);
+	bool (*rx_desc_dot11_hdr_fields_valid)(struct hal_rx_desc *desc);
+	void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc,
+				      struct ieee80211_hdr *hdr);
+	void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc,
+					  u8 *crypto_hdr,
+					  enum hal_encrypt_type enctype);
 };
 
 extern const struct ath11k_hw_ops ipq8074_ops;
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5691,6 +5691,7 @@ static int ath11k_mac_config_mon_status_
 			tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar);
 	}
 
+	tlv_filter.offset_valid = false;
 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
--- a/drivers/net/wireless/ath/ath11k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath11k/rx_desc.h
@@ -1375,9 +1375,11 @@ struct hal_rx_desc_ipq8074 {
 	__le32 mpdu_end_tag;
 	struct rx_mpdu_end mpdu_end;
 	u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES];
+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M
 	__le32 hdr_status_tag;
 	__le32 phy_ppdu_id;
 	u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN];
+#endif
 	u8 msdu_payload[0];
 } __packed;
 
@@ -1394,9 +1396,11 @@ struct hal_rx_desc_qcn9074 {
 	__le32 mpdu_end_tag;
 	struct rx_mpdu_end mpdu_end;
 	u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES];
+#ifndef CPTCFG_ATH11K_MEM_PROFILE_512M
 	__le32 hdr_status_tag;
 	__le32 phy_ppdu_id;
 	u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN];
+#endif
 	u8 msdu_payload[0];
 } __packed;
 
@@ -1420,4 +1424,17 @@ struct hal_rx_desc {
 #define RU_484 18
 #define RU_996 37
 
+#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \
+	FIELD_GET(GENMASK(7, 0), __le32_to_cpu(__val))
+
+#define HAL_RX_MPDU_INFO_PN_GET_BYTE2(__val) \
+	FIELD_GET(GENMASK(15, 8), __le32_to_cpu(__val))
+
+#define HAL_RX_MPDU_INFO_PN_GET_BYTE3(__val) \
+	FIELD_GET(GENMASK(23, 16), __le32_to_cpu(__val))
+
+#define HAL_RX_MPDU_INFO_PN_GET_BYTE4(__val) \
+	FIELD_GET(GENMASK(31, 24), __le32_to_cpu(__val))
+
+
 #endif /* ATH11K_RX_DESC_H */
--- a/drivers/net/wireless/ath/ath11k/nss.c
+++ b/drivers/net/wireless/ath/ath11k/nss.c
@@ -2168,7 +2168,7 @@ static int ath11k_nss_init(struct ath11k
 
 	/* fill rx parameters to initialize rx context */
 	wim->wrip.tlv_size = sizeof(struct hal_rx_desc);
-	wim->wrip.rx_buf_len = DP_RX_BUFFER_SIZE;
+	wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE;
 
 	/* fill hal srng message */
 	wim->hssm.dev_base_addr = (u32)ab->mem_pa;
