Explorar o código

qcacmn: add abstraction to update rx stats

Add a new API to update the stats which will be
called from dp_rx_process instead of updating stats
directly from within the dp_rx_process function

Change-Id: I13bdfd1606c3ceb2e38921ffa0cf3fe9f29c57ee
CRs-Fixed: 2189088
Tallapragada Kalyan %!s(int64=7) %!d(string=hai) anos
pai
achega
e33a5632b8
Modificáronse 2 ficheiros con 189 adicións e 174 borrados
  1. 162 174
      dp/wifi3.0/dp_rx.c
  2. 27 0
      dp/wifi3.0/hal_rx.h

+ 162 - 174
dp/wifi3.0/dp_rx.c

@@ -994,6 +994,143 @@ static inline void dp_rx_deliver_to_stack(struct dp_vdev *vdev,
 
 }
 
+/**
+ * dp_rx_cksum_offload() - set the nbuf checksum as defined by hardware.
+ * @nbuf: pointer to the first msdu of an amsdu.
+ * @rx_tlv_hdr: pointer to the start of RX TLV headers.
+ *
+ * The ipsumed field of the skb is set based on whether HW validated the
+ * IP/TCP/UDP checksum.
+ *
+ * Return: void
+ */
+static inline void dp_rx_cksum_offload(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr)
+{
+	qdf_nbuf_rx_cksum_t cksum = {0};
+
+	if (qdf_likely(!hal_rx_attn_tcp_udp_cksum_fail_get(rx_tlv_hdr) &&
+		       !hal_rx_attn_ip_cksum_fail_get(rx_tlv_hdr))) {
+		cksum.l4_result = QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY;
+
+		qdf_nbuf_set_rx_cksum(nbuf, &cksum);
+	}
+}
+
+/**
+ * dp_rx_msdu_stats_update() - update per msdu stats.
+ * @soc: core txrx main context
+ * @nbuf: pointer to the first msdu of an amsdu.
+ * @rx_tlv_hdr: pointer to the start of RX TLV headers.
+ * @peer: pointer to the peer object.
+ * @ring_id: reo dest ring number on which pkt is reaped.
+ *
+ * update all the per msdu stats for that nbuf.
+ * Return: void
+ */
+static void dp_rx_msdu_stats_update(struct dp_soc *soc,
+				    qdf_nbuf_t nbuf,
+				    uint8_t *rx_tlv_hdr,
+				    struct dp_peer *peer,
+				    uint8_t ring_id)
+{
+	bool is_ampdu, is_not_amsdu;
+	uint16_t peer_id;
+	uint32_t sgi, mcs, tid, nss, bw, reception_type, pkt_type;
+	struct dp_vdev *vdev = peer->vdev;
+	struct ether_header *eh;
+	bool is_broadcast = false;
+
+	peer_id = DP_PEER_METADATA_PEER_ID_GET(
+			       hal_rx_mpdu_peer_meta_data_get(rx_tlv_hdr));
+
+	is_not_amsdu = qdf_nbuf_is_rx_chfrag_start(nbuf) &
+			qdf_nbuf_is_rx_chfrag_end(nbuf);
+
+	DP_STATS_INC_PKT(peer, rx.rcvd_reo[ring_id], 1,
+			 hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr));
+
+	DP_STATS_INCC(peer, rx.non_amsdu_cnt, 1, is_not_amsdu);
+	DP_STATS_INCC(peer, rx.amsdu_cnt, 1, !is_not_amsdu);
+
+	DP_STATS_INCC_PKT(peer, rx.multicast, 1, qdf_nbuf_len(nbuf),
+			  hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr));
+
+	/*
+	 * currently we can return from here as we have similar stats
+	 * updated at per ppdu level instead of msdu level
+	 */
+	if (!soc->process_rx_status)
+		return;
+
+	is_ampdu = hal_rx_mpdu_info_ampdu_flag_get(rx_tlv_hdr);
+	DP_STATS_INCC(peer, rx.ampdu_cnt, 1, is_ampdu);
+	DP_STATS_INCC(peer, rx.non_ampdu_cnt, 1, !(is_ampdu));
+
+	sgi = hal_rx_msdu_start_sgi_get(rx_tlv_hdr);
+	mcs = hal_rx_msdu_start_rate_mcs_get(rx_tlv_hdr);
+	tid = hal_rx_mpdu_start_tid_get(rx_tlv_hdr);
+	bw = hal_rx_msdu_start_bw_get(rx_tlv_hdr);
+	reception_type = hal_rx_msdu_start_reception_type_get(rx_tlv_hdr);
+	nss = hal_rx_msdu_start_nss_get(rx_tlv_hdr);
+	pkt_type = hal_rx_msdu_start_get_pkt_type(rx_tlv_hdr);
+
+	DP_STATS_INC(vdev->pdev, rx.bw[bw], 1);
+	DP_STATS_INC(vdev->pdev, rx.reception_type[reception_type], 1);
+	DP_STATS_INCC(vdev->pdev, rx.nss[nss], 1,
+		      ((reception_type == REPT_MU_MIMO) ||
+		       (reception_type == REPT_MU_OFDMA_MIMO)));
+	DP_STATS_INC(peer, rx.sgi_count[sgi], 1);
+	DP_STATS_INCC(peer, rx.err.mic_err, 1,
+		      hal_rx_mpdu_end_mic_err_get(rx_tlv_hdr));
+	DP_STATS_INCC(peer, rx.err.decrypt_err, 1,
+		      hal_rx_mpdu_end_decrypt_err_get(rx_tlv_hdr));
+
+	DP_STATS_INC(peer, rx.wme_ac_type[TID_TO_WME_AC(tid)], 1);
+	DP_STATS_INC(peer, rx.bw[bw], 1);
+	DP_STATS_INC(peer, rx.reception_type[reception_type], 1);
+
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[MAX_MCS], 1,
+		      ((mcs >= MAX_MCS_11A) && (pkt_type == DOT11_A)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[mcs], 1,
+		      ((mcs <= MAX_MCS_11A) && (pkt_type == DOT11_A)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[MAX_MCS], 1,
+		      ((mcs >= MAX_MCS_11B) && (pkt_type == DOT11_B)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[mcs], 1,
+		      ((mcs <= MAX_MCS_11B) && (pkt_type == DOT11_B)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[MAX_MCS], 1,
+		      ((mcs >= MAX_MCS_11A) && (pkt_type == DOT11_N)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[mcs], 1,
+		      ((mcs <= MAX_MCS_11A) && (pkt_type == DOT11_N)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[MAX_MCS], 1,
+		      ((mcs >= MAX_MCS_11AC) && (pkt_type == DOT11_AC)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[mcs], 1,
+		      ((mcs <= MAX_MCS_11AC) && (pkt_type == DOT11_AC)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[MAX_MCS], 1,
+		      ((mcs >= MAX_MCS) && (pkt_type == DOT11_AX)));
+	DP_STATS_INCC(peer, rx.pkt_type[pkt_type].mcs_count[mcs], 1,
+		      ((mcs <= MAX_MCS) && (pkt_type == DOT11_AX)));
+
+	if (qdf_unlikely(hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr) &&
+			 (vdev->rx_decap_type == htt_cmn_pkt_type_ethernet))) {
+		eh = (struct ether_header *)qdf_nbuf_data(nbuf);
+		is_broadcast =
+			IEEE80211_IS_BROADCAST(eh->ether_dhost) ? true : false;
+		if (is_broadcast)
+			DP_STATS_INC_PKT(peer, rx.bcast, 1, qdf_nbuf_len(nbuf));
+	}
+
+	if ((soc->process_rx_status) &&
+	    hal_rx_attn_first_mpdu_get(rx_tlv_hdr)) {
+		if (soc->cdp_soc.ol_ops->update_dp_stats) {
+			soc->cdp_soc.ol_ops->update_dp_stats(
+					vdev->pdev->osif_pdev,
+					&peer->stats,
+					peer_id,
+					UPDATE_PEER_STATS);
+		}
+	}
+}
+
 #ifdef WDS_VENDOR_EXTENSION
 int dp_wds_rx_policy_check(
 		uint8_t *rx_tlv_hdr,
@@ -1119,18 +1256,14 @@ dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota)
 	uint32_t peer_mdata;
 	uint8_t *rx_tlv_hdr;
 	uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 };
-	uint32_t sgi, mcs, tid, nss, bw, reception_type, pkt_type;
 	uint8_t mac_id = 0;
-	uint32_t ampdu_flag, amsdu_flag;
 	struct dp_pdev *pdev;
 	struct dp_srng *dp_rxdma_srng;
 	struct rx_desc_pool *rx_desc_pool;
-	struct ether_header *eh;
 	struct dp_soc *soc = int_ctx->soc;
 	uint8_t ring_id = 0;
 	uint8_t core_id = 0;
 	bool is_first_frag = 0;
-	bool isBroadcast = 0;
 	uint16_t mpdu_len = 0;
 	qdf_nbuf_t head_frag_nbuf = NULL;
 	qdf_nbuf_t frag_list_head = NULL;
@@ -1151,7 +1284,6 @@ dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota)
 	qdf_assert(hal_soc);
 
 	hif_pm_runtime_mark_last_busy(soc->osdev->dev);
-	sgi = mcs = tid = nss = bw = reception_type = pkt_type = 0;
 
 	if (qdf_unlikely(hal_srng_access_start(hal_soc, hal_ring))) {
 
@@ -1206,26 +1338,10 @@ dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota)
 
 		/* Get MPDU DESC info */
 		hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info);
-		peer_id = DP_PEER_METADATA_PEER_ID_GET(
-				mpdu_desc_info.peer_meta_data);
 
 		hal_rx_mpdu_peer_meta_data_set(qdf_nbuf_data(rx_desc->nbuf),
 						mpdu_desc_info.peer_meta_data);
 
-		peer = dp_peer_find_by_id(soc, peer_id);
-
-		vdev = dp_get_vdev_from_peer(soc, peer_id, peer,
-						mpdu_desc_info);
-
-		if (!vdev) {
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW,
-				FL("vdev is NULL"));
-			DP_STATS_INC(soc, rx.err.invalid_vdev, 1);
-			qdf_nbuf_free(rx_desc->nbuf);
-			goto fail;
-
-		}
-
 		/* Get MSDU DESC info */
 		hal_rx_msdu_desc_info_get(ring_desc, &msdu_desc_info);
 
@@ -1242,30 +1358,8 @@ dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota)
 		if (msdu_desc_info.msdu_flags & HAL_MSDU_F_LAST_MSDU_IN_MPDU)
 			qdf_nbuf_set_rx_chfrag_end(rx_desc->nbuf, 1);
 
-		DP_STATS_INC_PKT(peer, rx.rcvd_reo[ring_id], 1,
-				qdf_nbuf_len(rx_desc->nbuf));
-
-		if (soc->process_rx_status) {
-			ampdu_flag = (mpdu_desc_info.mpdu_flags &
-					HAL_MPDU_F_AMPDU_FLAG);
-
-			DP_STATS_INCC(peer, rx.ampdu_cnt, 1, ampdu_flag);
-			DP_STATS_INCC(peer, rx.non_ampdu_cnt, 1, !(ampdu_flag));
-		}
-
-		amsdu_flag = ((msdu_desc_info.msdu_flags &
-					HAL_MSDU_F_FIRST_MSDU_IN_MPDU) &&
-				(msdu_desc_info.msdu_flags &
-					HAL_MSDU_F_LAST_MSDU_IN_MPDU));
-
-		DP_STATS_INCC(peer, rx.non_amsdu_cnt, 1,
-				amsdu_flag);
-		DP_STATS_INCC(peer, rx.amsdu_cnt, 1,
-				!(amsdu_flag));
-
-		DP_HIST_PACKET_COUNT_INC(vdev->pdev->pdev_id);
 		DP_RX_LIST_APPEND(nbuf_head, nbuf_tail, rx_desc->nbuf);
-fail:
+
 		/*
 		 * if continuation bit is set then we have MSDU spread
 		 * across multiple buffers, let us not decrement quota
@@ -1307,15 +1401,35 @@ done:
 	if (qdf_likely(peer != NULL))
 		vdev = NULL;
 
+	/*
+	 * BIG loop where each nbuf is dequeued from global queue,
+	 * processed and queued back on a per vdev basis. These nbufs
+	 * are sent to stack as and when we run out of nbufs
+	 * or a new nbuf dequeued from global queue has a different
+	 * vdev when compared to previous nbuf.
+	 */
 	nbuf = nbuf_head;
 	while (nbuf) {
 		next = nbuf->next;
 		rx_tlv_hdr = qdf_nbuf_data(nbuf);
 
+		/*
+		 * Check if DMA completed -- msdu_done is the last bit
+		 * to be written
+		 */
+		if (qdf_unlikely(!hal_rx_attn_msdu_done_get(rx_tlv_hdr))) {
+			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				  FL("MSDU DONE failure"));
+			hal_rx_dump_pkt_tlvs(rx_tlv_hdr, QDF_TRACE_LEVEL_INFO);
+			qdf_assert(0);
+		}
+
 		peer_mdata = hal_rx_mpdu_peer_meta_data_get(rx_tlv_hdr);
 		peer_id = DP_PEER_METADATA_PEER_ID_GET(peer_mdata);
 		peer = dp_peer_find_by_id(soc, peer_id);
 
+		rx_bufs_used++;
+
 		if (deliver_list_head && peer && (vdev != peer->vdev)) {
 			dp_rx_deliver_to_stack(vdev, peer, deliver_list_head);
 			deliver_list_head = NULL;
@@ -1337,21 +1451,7 @@ done:
 			continue;
 		}
 
-		/*
-		 * Check if DMA completed -- msdu_done is the last bit
-		 * to be written
-		 */
-		if (!hal_rx_attn_msdu_done_get(rx_tlv_hdr)) {
-
-			QDF_TRACE(QDF_MODULE_ID_DP,
-					QDF_TRACE_LEVEL_ERROR,
-					FL("MSDU DONE failure"));
-			DP_STATS_INC(vdev->pdev, dropped.msdu_not_done,
-					1);
-			hal_rx_dump_pkt_tlvs(rx_tlv_hdr, QDF_TRACE_LEVEL_INFO);
-			qdf_assert(0);
-		}
-
+		DP_HIST_PACKET_COUNT_INC(vdev->pdev->pdev_id);
 		/*
 		 * The below condition happens when an MSDU is spread
 		 * across multiple buffers. This can happen in two cases
@@ -1390,7 +1490,7 @@ done:
 		}
 
 		if (!dp_wds_rx_policy_check(rx_tlv_hdr, vdev, peer,
-					hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) {
+				hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) {
 			QDF_TRACE(QDF_MODULE_ID_DP,
 					QDF_TRACE_LEVEL_ERROR,
 					FL("Policy Check Drop pkt"));
@@ -1414,8 +1514,6 @@ done:
 			continue;
 		}
 
-		pdev = vdev->pdev;
-
 		if (qdf_unlikely(peer && (peer->nawds_enabled == true) &&
 			(hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr)) &&
 			(hal_rx_get_mpdu_mac_ad4_valid(rx_tlv_hdr) == false))) {
@@ -1426,91 +1524,9 @@ done:
 			continue;
 		}
 
-		if (qdf_likely(
-			!hal_rx_attn_tcp_udp_cksum_fail_get(rx_tlv_hdr)
-			&&
-			!hal_rx_attn_ip_cksum_fail_get(rx_tlv_hdr))) {
-			qdf_nbuf_rx_cksum_t cksum = {0};
-
-			cksum.l4_result =
-				QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY;
-
-			qdf_nbuf_set_rx_cksum(nbuf, &cksum);
-		}
-
-		if (soc->process_rx_status) {
-			sgi = hal_rx_msdu_start_sgi_get(rx_tlv_hdr);
-			mcs = hal_rx_msdu_start_rate_mcs_get(rx_tlv_hdr);
-			tid = hal_rx_mpdu_start_tid_get(rx_tlv_hdr);
-
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
-				"%s: %d, SGI: %d, tid: %d",
-				__func__, __LINE__, sgi, tid);
-
-			bw = hal_rx_msdu_start_bw_get(rx_tlv_hdr);
-			reception_type = hal_rx_msdu_start_reception_type_get(
-					rx_tlv_hdr);
-			nss = hal_rx_msdu_start_nss_get(rx_tlv_hdr);
-			pkt_type = hal_rx_msdu_start_get_pkt_type(rx_tlv_hdr);
-
-			DP_STATS_INC(peer, rx.nss[nss], 1);
+		dp_rx_cksum_offload(nbuf, rx_tlv_hdr);
 
-			DP_STATS_INCC(peer, rx.err.mic_err, 1,
-				hal_rx_mpdu_end_mic_err_get(
-					rx_tlv_hdr));
-
-			DP_STATS_INCC(peer, rx.err.decrypt_err, 1,
-				hal_rx_mpdu_end_decrypt_err_get(
-					rx_tlv_hdr));
-
-			DP_STATS_INC(peer, rx.reception_type[reception_type],
-					1);
-			DP_STATS_INC(peer, rx.bw[bw], 1);
-			DP_STATS_INC(peer, rx.sgi_count[sgi], 1);
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[MAX_MCS - 1], 1,
-					((mcs >= MAX_MCS_11A) &&
-					 (pkt_type == DOT11_A)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[mcs], 1,
-					((mcs < MAX_MCS_11A) &&
-					 (pkt_type == DOT11_A)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[MAX_MCS - 1], 1,
-					((mcs >= MAX_MCS_11B) &&
-					 (pkt_type == DOT11_B)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[mcs], 1,
-					((mcs < MAX_MCS_11B) &&
-					 (pkt_type == DOT11_B)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[MAX_MCS - 1], 1,
-					((mcs >= MAX_MCS_11A) &&
-					 (pkt_type == DOT11_N)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[mcs], 1,
-					((mcs < MAX_MCS_11A) &&
-					 (pkt_type == DOT11_N)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[MAX_MCS - 1], 1,
-					((mcs >= MAX_MCS_11AC) &&
-					 (pkt_type == DOT11_AC)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[mcs], 1,
-					((mcs < MAX_MCS_11AC) &&
-					 (pkt_type == DOT11_AC)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[MAX_MCS - 1], 1,
-					((mcs >= (MAX_MCS - 1)) &&
-					 (pkt_type == DOT11_AX)));
-			DP_STATS_INCC(peer, rx.pkt_type[pkt_type].
-					mcs_count[mcs], 1,
-					((mcs < (MAX_MCS - 1)) &&
-					 (pkt_type == DOT11_AX)));
-
-			DP_STATS_INC(peer, rx.wme_ac_type[TID_TO_WME_AC(tid)],
-					1);
-		}
+		dp_rx_msdu_stats_update(soc, nbuf, rx_tlv_hdr, peer, ring_id);
 
 		/*
 		 * HW structures call this L3 header padding --
@@ -1584,43 +1600,15 @@ done:
 				}
 		}
 
-		rx_bufs_used++;
-
 		dp_rx_lro(rx_tlv_hdr, peer, nbuf, int_ctx->lro_ctx);
 
 		DP_RX_LIST_APPEND(deliver_list_head,
 					deliver_list_tail,
 					nbuf);
 
-		DP_STATS_INCC_PKT(peer, rx.multicast, 1, qdf_nbuf_len(nbuf),
-				hal_rx_msdu_end_da_is_mcbc_get(
-					rx_tlv_hdr));
-
 		DP_STATS_INC_PKT(peer, rx.to_stack, 1,
 				qdf_nbuf_len(nbuf));
 
-		if (qdf_unlikely(hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr) &&
-					(vdev->rx_decap_type ==
-					 htt_cmn_pkt_type_ethernet))) {
-			eh = (struct ether_header *)qdf_nbuf_data(nbuf);
-			isBroadcast = (IEEE80211_IS_BROADCAST
-					(eh->ether_dhost)) ? 1 : 0 ;
-			if (isBroadcast) {
-				DP_STATS_INC_PKT(peer, rx.bcast, 1,
-						qdf_nbuf_len(nbuf));
-			}
-		}
-
-		if ((soc->process_rx_status) && likely(peer) &&
-			hal_rx_attn_first_mpdu_get(rx_tlv_hdr)) {
-			if (soc->cdp_soc.ol_ops->update_dp_stats) {
-				soc->cdp_soc.ol_ops->update_dp_stats(
-						vdev->pdev->osif_pdev,
-						&peer->stats,
-						peer_id,
-						UPDATE_PEER_STATS);
-			}
-		}
 		nbuf = next;
 	}
 

+ 27 - 0
dp/wifi3.0/hal_rx.h

@@ -827,6 +827,33 @@ hal_rx_mpdu_peer_meta_data_get(uint8_t *buf)
 	return peer_meta_data;
 }
 
+#define HAL_RX_MPDU_INFO_AMPDU_FLAG_GET(_rx_mpdu_info)	\
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info,	\
+		RX_MPDU_INFO_12_AMPDU_FLAG_OFFSET)),	\
+		RX_MPDU_INFO_12_AMPDU_FLAG_MASK,	\
+		RX_MPDU_INFO_12_AMPDU_FLAG_LSB))
+/**
+ * hal_rx_mpdu_info_ampdu_flag_get(): get ampdu flag bit
+ * from rx mpdu info
+ * @buf: pointer to rx_pkt_tlvs
+ *
+ * Return: ampdu flag
+ */
+static inline bool
+hal_rx_mpdu_info_ampdu_flag_get(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_mpdu_start *mpdu_start =
+				 &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
+
+	struct rx_mpdu_info *mpdu_info = &mpdu_start->rx_mpdu_info_details;
+	bool ampdu_flag;
+
+	ampdu_flag = HAL_RX_MPDU_INFO_AMPDU_FLAG_GET(mpdu_info);
+
+	return ampdu_flag;
+}
+
 #define HAL_RX_MPDU_PEER_META_DATA_SET(_rx_mpdu_info, peer_mdata)	\
 		((*(((uint32_t *)_rx_mpdu_info) +			\
 		(RX_MPDU_INFO_8_PEER_META_DATA_OFFSET >> 2))) =		\