Browse Source

qcacmn: fix the stats counter in raw mode

use hal_msdu_len instead of qdf_nbuf_len to get
the packet length and correct the packet length
for first msdu of a amsdu

Change-Id: I7410cb6bd98743f3b01019c9e394c32c77c3a30e
CRs-Fixed: 2228232
Chaithanya Garrepalli 6 years ago
parent
commit
a173a184ae
1 changed files with 53 additions and 29 deletions
  1. 53 29
      dp/wifi3.0/dp_rx.c

+ 53 - 29
dp/wifi3.0/dp_rx.c

@@ -960,6 +960,7 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr)
 	uint16_t mpdu_len;
 	bool last_nbuf;
 
+	mpdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr);
 	/*
 	 * this is a case where the complete msdu fits in one single nbuf.
 	 * in this case HW sets both start and end bit and we only need to
@@ -967,8 +968,8 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr)
 	 */
 	if (qdf_nbuf_is_rx_chfrag_start(nbuf) &&
 					qdf_nbuf_is_rx_chfrag_end(nbuf)) {
-		qdf_nbuf_set_rx_chfrag_start(nbuf, 0);
-		qdf_nbuf_set_rx_chfrag_end(nbuf, 0);
+		qdf_nbuf_set_pktlen(nbuf, mpdu_len + RX_PKT_TLVS_LEN);
+		qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
 		return nbuf;
 	}
 
@@ -991,7 +992,6 @@ qdf_nbuf_t dp_rx_sg_create(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr)
 	 * nbufs will form the frag_list of the parent nbuf.
 	 */
 	qdf_nbuf_set_rx_chfrag_start(parent, 1);
-	mpdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr);
 	last_nbuf = dp_rx_adjust_nbuf_len(parent, &mpdu_len);
 
 	/*
@@ -1303,11 +1303,11 @@ dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota)
 	union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL };
 	uint32_t rx_bufs_used = 0, rx_buf_cookie;
 	uint32_t l2_hdr_offset = 0;
-	uint16_t msdu_len;
+	uint16_t msdu_len = 0;
 	uint16_t peer_id;
 	struct dp_peer *peer = NULL;
 	struct dp_vdev *vdev = NULL;
-	uint32_t pkt_len;
+	uint32_t pkt_len = 0;
 	struct hal_rx_mpdu_desc_info mpdu_desc_info = { 0 };
 	struct hal_rx_msdu_desc_info msdu_desc_info = { 0 };
 	enum hal_reo_error_status error;
@@ -1355,8 +1355,28 @@ dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota)
 	 * them in per vdev queue.
 	 * Process the received pkts in a different per vdev loop.
 	 */
-	while (qdf_likely(quota && (ring_desc =
-				hal_srng_dst_get_next(hal_soc, hal_ring)))) {
+	while (qdf_likely(quota)) {
+		ring_desc = hal_srng_dst_get_next(hal_soc, hal_ring);
+
+		/*
+		 * in case HW has updated hp after we cached the hp
+		 * ring_desc can be NULL even there are entries
+		 * available in the ring. Update the cached_hp
+		 * and reap the buffers available to read complete
+		 * mpdu in one reap
+		 *
+		 * This is needed for RAW mode we have to read all
+		 * msdus corresponding to amsdu in one reap to create
+		 * SG list properly but due to mismatch in cached_hp
+		 * and actual hp sometimes we are unable to read
+		 * complete mpdu in one reap.
+		 */
+		if (qdf_unlikely(!ring_desc)) {
+			hal_srng_access_start_unlocked(hal_soc, hal_ring);
+			ring_desc = hal_srng_dst_get_next(hal_soc, hal_ring);
+			if (!ring_desc)
+				break;
+		}
 
 		error = HAL_RX_ERROR_STATUS_GET(ring_desc);
 		ring_id = hal_srng_ring_id_get(hal_ring);
@@ -1505,6 +1525,11 @@ done:
 
 		DP_HIST_PACKET_COUNT_INC(vdev->pdev->pdev_id);
 		/*
+		 * First IF condition:
+		 * 802.11 Fragmented pkts are reinjected to REO
+		 * HW block as SG pkts and for these pkts we only
+		 * need to pull the RX TLVS header length.
+		 * Second IF condition:
 		 * The below condition happens when an MSDU is spread
 		 * across multiple buffers. This can happen in two cases
 		 * 1. The nbuf size is smaller then the received msdu.
@@ -1520,15 +1545,33 @@ done:
 		 *
 		 * for these scenarios let us create a skb frag_list and
 		 * append these buffers till the last MSDU of the AMSDU
+		 * Third condition:
+		 * This is the most likely case, we receive 802.3 pkts
+		 * decapsulated by HW, here we need to set the pkt length.
 		 */
-		if (qdf_unlikely(vdev->rx_decap_type ==
+		if (qdf_unlikely(qdf_nbuf_get_ext_list(nbuf)))
+			qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
+		else if (qdf_unlikely(vdev->rx_decap_type ==
 				htt_cmn_pkt_type_raw)) {
+			msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr);
+			nbuf = dp_rx_sg_create(nbuf, rx_tlv_hdr);
 
 			DP_STATS_INC(vdev->pdev, rx_raw_pkts, 1);
-			DP_STATS_INC_PKT(peer, rx.raw, 1, qdf_nbuf_len(nbuf));
+			DP_STATS_INC_PKT(peer, rx.raw, 1,
+					 msdu_len);
 
-			nbuf = dp_rx_sg_create(nbuf, rx_tlv_hdr);
 			next = nbuf->next;
+		} else {
+			l2_hdr_offset =
+				hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr);
+
+			msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr);
+			pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN;
+
+			qdf_nbuf_set_pktlen(nbuf, pkt_len);
+			qdf_nbuf_pull_head(nbuf,
+					   RX_PKT_TLVS_LEN +
+					   l2_hdr_offset);
 		}
 
 		if (!dp_wds_rx_policy_check(rx_tlv_hdr, vdev, peer,
@@ -1579,25 +1622,6 @@ done:
 			FL("rxhash: flow id toeplitz: 0x%x\n"),
 			hal_rx_msdu_start_toeplitz_get(rx_tlv_hdr));
 
-		/*L2 header offset will not be set in raw mode*/
-		if (qdf_likely(vdev->rx_decap_type !=
-				htt_cmn_pkt_type_raw)) {
-			l2_hdr_offset =
-				hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr);
-		}
-
-		msdu_len = hal_rx_msdu_start_msdu_len_get(rx_tlv_hdr);
-		pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN;
-
-		if (unlikely(qdf_nbuf_get_ext_list(nbuf)))
-			qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
-		else {
-			qdf_nbuf_set_pktlen(nbuf, pkt_len);
-			qdf_nbuf_pull_head(nbuf,
-					RX_PKT_TLVS_LEN +
-					l2_hdr_offset);
-		}
-
 		dp_rx_msdu_stats_update(soc, nbuf, rx_tlv_hdr, peer, ring_id);
 
 		if (qdf_unlikely(vdev->mesh_vdev)) {