ソースを参照

qcacmn: fix rx path dma-inv-range, unmap-single issues

In case of duplicated rx descriptors from hardware,
it will hit issues in __dma_inv_range(), __qdf_nbuf_unmap_single.
Detect the duplicates, skip processing them, drop the mpdu.

CRs-Fixed: 2413816
Change-Id: I7efd4b0c1bda5578578927bb22fe9d487758897d
nwzhao 6 年 前
コミット
d7196d8dd4
2 ファイル変更24 行追加7 行削除
  1. 17 6
      dp/wifi3.0/dp_rx_mon_dest.c
  2. 7 1
      hal/wifi3.0/hal_rx.h

+ 17 - 6
dp/wifi3.0/dp_rx_mon_dest.c

@@ -273,6 +273,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
 	bool is_frag, is_first_msdu;
 	bool drop_mpdu = false;
 	uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
+	uint64_t nbuf_paddr = 0;
 
 	msdu = 0;
 
@@ -318,21 +319,29 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
 			uint32_t l2_hdr_offset;
 			struct dp_rx_desc *rx_desc = NULL;
 
+			rx_desc = dp_rx_get_mon_desc(soc,
+						     msdu_list.sw_cookie[i]);
+
+			qdf_assert_always(rx_desc);
+			msdu = rx_desc->nbuf;
+
+			if (msdu)
+				nbuf_paddr = qdf_nbuf_get_frag_paddr(msdu, 0);
 			/* WAR for duplicate buffers received from HW */
 			if (qdf_unlikely(dp_pdev->mon_last_buf_cookie ==
-			    msdu_list.sw_cookie[i])) {
+				msdu_list.sw_cookie[i] ||
+				!msdu ||
+				msdu_list.paddr[i] != nbuf_paddr ||
+				!rx_desc->in_use)) {
 				/* Skip duplicate buffer and drop subsequent
 				 * buffers in this MPDU
 				 */
 				drop_mpdu = true;
 				dp_pdev->rx_mon_stats.dup_mon_buf_cnt++;
+				dp_pdev->mon_last_linkdesc_paddr =
+					buf_info.paddr;
 				continue;
 			}
-			rx_desc = dp_rx_get_mon_desc(soc,
-						     msdu_list.sw_cookie[i]);
-
-			qdf_assert_always(rx_desc);
-			msdu = rx_desc->nbuf;
 
 			if (rx_desc->unmapped == 0) {
 				qdf_nbuf_unmap_single(soc->osdev, msdu,
@@ -341,6 +350,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
 			}
 
 			if (drop_mpdu) {
+				dp_pdev->mon_last_linkdesc_paddr =
+					buf_info.paddr;
 				qdf_nbuf_free(msdu);
 				msdu = NULL;
 				goto next_msdu;

+ 7 - 1
hal/wifi3.0/hal_rx.h

@@ -1941,6 +1941,8 @@ struct hal_rx_msdu_list {
 	struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC];
 	uint32_t sw_cookie[HAL_RX_NUM_MSDU_DESC];
 	uint8_t rbm[HAL_RX_NUM_MSDU_DESC];
+	/* physical address of the msdu */
+	uint64_t paddr[HAL_RX_NUM_MSDU_DESC];
 };
 
 struct hal_buf_info {
@@ -2038,8 +2040,12 @@ static inline void hal_rx_msdu_list_get(struct hal_soc *hal_soc,
 		msdu_list->sw_cookie[i] =
 			 HAL_RX_BUF_COOKIE_GET(
 				&msdu_details[i].buffer_addr_info_details);
-		 msdu_list->rbm[i] = HAL_RX_BUF_RBM_GET(
+		msdu_list->rbm[i] = HAL_RX_BUF_RBM_GET(
 				&msdu_details[i].buffer_addr_info_details);
+		msdu_list->paddr[i] = HAL_RX_BUFFER_ADDR_31_0_GET(
+			   &msdu_details[i].buffer_addr_info_details) |
+			   (uint64_t)HAL_RX_BUFFER_ADDR_39_32_GET(
+			   &msdu_details[i].buffer_addr_info_details) << 32;
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			"[%s][%d] i=%d sw_cookie=%d",
 			__func__, __LINE__, i, msdu_list->sw_cookie[i]);