瀏覽代碼

qcacmn: Access mpdu start tlv only for first msdu-in-mpdu

Currently the mpdu level flags/values are obtained
from the MPDU_START tlv of each msdu, when processing
in the RX error path.

The MPDU_START tlv is valid in an msdu only if it is
the first msdu-in-mpdu and will not be valid for all
the subsequent msdus-in-mpdu.

Accessing and using the incorrect values from the
MPDU_START tlv leads to unwanted exception/behaviour.

To fix the above mentioned issue, cache the mpdu level
information from the tlv when processing the first
msdu-in-mpdu and use it for the processing of the
subsequent msdus from the same mpdu.

Change-Id: Ic0b47716d3d428bb0b536c4ee23c1392f183d1fe
CRs-Fixed: 3306327
Rakesh Pillai 2 年之前
父節點
當前提交
21bce3501c
共有 1 個文件被更改,包括 32 次插入23 次删除
  1. 32 23
      dp/wifi3.0/dp_rx_err.c

+ 32 - 23
dp/wifi3.0/dp_rx_err.c

@@ -1561,27 +1561,22 @@ more_msdu_link_desc:
 			goto process_next_msdu;
 		}
 
-		hal_rx_tlv_populate_mpdu_desc_info(soc->hal_soc,
-						   qdf_nbuf_data(head_nbuf),
-						   mpdu_desc_info);
-		if (qdf_unlikely(mpdu_desc_info->mpdu_flags &
-				 HAL_MPDU_F_RAW_AMPDU)) {
-			dp_err_rl("RAW ampdu in REO error not expected");
-			DP_STATS_INC(soc, rx.err.reo_err_raw_mpdu_drop, 1);
-			qdf_nbuf_list_free(head_nbuf);
-			goto process_next_msdu;
-		}
-
-		rx_tlv_hdr_first = qdf_nbuf_data(head_nbuf);
-		rx_tlv_hdr_last = qdf_nbuf_data(tail_nbuf);
-
-		if (qdf_unlikely(head_nbuf != tail_nbuf)) {
-			nbuf = dp_rx_sg_create(soc, head_nbuf);
-			qdf_nbuf_set_is_frag(nbuf, 1);
-			DP_STATS_INC(soc, rx.err.reo_err_oor_sg_count, 1);
-		}
-
 		if (is_pn_check_needed) {
+			if (msdu_list.msdu_info[i].msdu_flags &
+			    HAL_MSDU_F_FIRST_MSDU_IN_MPDU) {
+				hal_rx_tlv_populate_mpdu_desc_info(
+							soc->hal_soc,
+							qdf_nbuf_data(nbuf),
+							mpdu_desc_info);
+			} else {
+				/*
+				 * DO NOTHING -
+				 * Continue using the same mpdu_desc_info
+				 * details populated from the first msdu in
+				 * the mpdu.
+				 */
+			}
+
 			status = dp_rx_err_nbuf_pn_check(soc, ring_desc, nbuf);
 			if (QDF_IS_STATUS_ERROR(status)) {
 				DP_STATS_INC(soc, rx.err.pn_in_dest_check_fail,
@@ -1590,9 +1585,6 @@ more_msdu_link_desc:
 				goto process_next_msdu;
 			}
 
-			hal_rx_tlv_populate_mpdu_desc_info(soc->hal_soc,
-							   qdf_nbuf_data(nbuf),
-							   mpdu_desc_info);
 			peer_id = dp_rx_peer_metadata_peer_id_get(soc,
 					mpdu_desc_info->peer_meta_data);
 
@@ -1603,6 +1595,23 @@ more_msdu_link_desc:
 							err_code);
 		}
 
+		if (qdf_unlikely(mpdu_desc_info->mpdu_flags &
+				 HAL_MPDU_F_RAW_AMPDU)) {
+			dp_err_rl("RAW ampdu in REO error not expected");
+			DP_STATS_INC(soc, rx.err.reo_err_raw_mpdu_drop, 1);
+			qdf_nbuf_list_free(head_nbuf);
+			goto process_next_msdu;
+		}
+
+		rx_tlv_hdr_first = qdf_nbuf_data(head_nbuf);
+		rx_tlv_hdr_last = qdf_nbuf_data(tail_nbuf);
+
+		if (qdf_unlikely(head_nbuf != tail_nbuf)) {
+			nbuf = dp_rx_sg_create(soc, head_nbuf);
+			qdf_nbuf_set_is_frag(nbuf, 1);
+			DP_STATS_INC(soc, rx.err.reo_err_oor_sg_count, 1);
+		}
+
 		switch (err_code) {
 		case HAL_REO_ERR_REGULAR_FRAME_2K_JUMP:
 		case HAL_REO_ERR_2K_ERROR_HANDLING_FLAG_SET: