Browse Source

qcacmn: Handle empty, flush and truncated ppdu in RxMON

In case of empty HW descriptor, sw cookie is not valid.
Instead, HW reports ppdu_drop_cnt, mpdu_drop_cnt and
tlv_drop_cnt.
Do not process sw desc, if it's empty HW desc indication.

In case of flush and trucanted PPDU, status buffer need to be discard,
added handling for same.

Change-Id: I1219f71645072bb9e0e80ff271fa354f305c7961
CRs-Fixed: 3144525
Amir Patel 3 years ago
parent
commit
b37c8d9550
2 changed files with 101 additions and 9 deletions
  1. 53 0
      dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c
  2. 48 9
      hal/wifi3.0/be/hal_be_api_mon.h

+ 53 - 0
dp/wifi3.0/monitor/2.0/dp_rx_mon_2.0.c

@@ -52,6 +52,35 @@ void dp_rx_mon_add_ppdu_info_to_wq(struct dp_mon_pdev_be *mon_pdev_be,
 	}
 }
 
+/**
+ * dp_rx_mon_handle_flush_n_trucated_ppdu () - Handle flush and truncated ppdu
+ *
+ * @soc: DP soc handle
+ * @pdev: pdev handle
+ * @mon_desc: mon sw desc
+ */
+static inline void
+dp_rx_mon_handle_flush_n_trucated_ppdu(struct dp_soc *soc,
+				       struct dp_pdev *pdev,
+				       struct dp_mon_desc *mon_desc)
+{
+	union dp_mon_desc_list_elem_t *desc_list = NULL;
+	union dp_mon_desc_list_elem_t *tail = NULL;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+	struct dp_mon_soc_be *mon_soc_be =
+			dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
+	struct dp_mon_desc_pool *rx_mon_desc_pool = &mon_soc_be->rx_desc_mon;
+	uint16_t work_done;
+
+	qdf_frag_free(mon_desc->buf_addr);
+	dp_mon_add_to_free_desc_list(&desc_list, &tail, mon_desc);
+	work_done = 1;
+	dp_mon_buffers_replenish(soc, &soc->rxdma_mon_buf_ring[0],
+				 rx_mon_desc_pool,
+				 work_done,
+				 &desc_list, &tail);
+}
+
 void dp_rx_mon_process_tlv_status(struct dp_pdev *pdev,
 				  struct hal_rx_ppdu_info *ppdu_info,
 				  void *status_frag,
@@ -337,6 +366,16 @@ dp_rx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
 		hal_be_get_mon_dest_status(soc->hal_soc,
 					   rx_mon_dst_ring_desc,
 					   &hal_mon_rx_desc);
+		/* If it's empty descriptor, skip processing
+		 * and process next hW desc
+		 */
+		if (hal_mon_rx_desc.empty_descriptor == 1) {
+			dp_mon_debug("empty descriptor found mon_pdev: %pK",
+				     mon_pdev);
+			rx_mon_dst_ring_desc =
+				hal_srng_dst_get_next(hal_soc, mon_dst_srng);
+			continue;
+		}
 		mon_desc = (struct dp_mon_desc *)(uintptr_t)(hal_mon_rx_desc.buf_addr);
 		qdf_assert_always(mon_desc);
 
@@ -348,6 +387,20 @@ dp_rx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
 		}
 		mon_desc->end_offset = hal_mon_rx_desc.end_offset;
 
+		/* Flush and truncated status buffers content
+		 * need to discarded
+		 */
+		if (hal_mon_rx_desc.end_reason == HAL_MON_FLUSH_DETECTED ||
+		    hal_mon_rx_desc.end_reason == HAL_MON_PPDU_TRUNCATED) {
+			dp_mon_debug("end_resaon: %d mon_pdev: %pK",
+				     hal_mon_rx_desc.end_reason, mon_pdev);
+			dp_rx_mon_handle_flush_n_trucated_ppdu(soc,
+							       pdev,
+							       mon_desc);
+			rx_mon_dst_ring_desc = hal_srng_dst_get_next(hal_soc,
+							mon_dst_srng);
+			continue;
+		}
 		if (desc_idx >= DP_MON_MAX_STATUS_BUF)
 			qdf_assert_always(0);
 

+ 48 - 9
hal/wifi3.0/be/hal_be_api_mon.h

@@ -288,6 +288,37 @@ typedef struct rx_mpdu_start hal_rx_mon_mpdu_start_t;
 typedef struct rx_msdu_end hal_rx_mon_msdu_end_t;
 #endif
 
+/*
+ * struct mon_destination_drop - monitor drop descriptor
+ *
+ * @ppdu_drop_cnt: PPDU drop count
+ * @mpdu_drop_cnt: MPDU drop count
+ * @tlv_drop_cnt: TLV drop count
+ * @end_of_ppdu_seen: end of ppdu seen
+ * @reserved_0a: rsvd
+ * @reserved_1a: rsvd
+ * @ppdu_id: PPDU ID
+ * @reserved_3a: rsvd
+ * @initiator: initiator ppdu
+ * @empty_descriptor: empty descriptor
+ * @ring_id: ring id
+ * @looping_count: looping count
+ */
+struct mon_destination_drop {
+	uint32_t ppdu_drop_cnt                     : 10,
+		 mpdu_drop_cnt                     : 10,
+		 tlv_drop_cnt                      : 10,
+		 end_of_ppdu_seen                  :  1,
+		 reserved_0a                       :  1;
+	uint32_t reserved_1a                       : 32;
+	uint32_t ppdu_id                           : 32;
+	uint32_t reserved_3a                       : 18,
+		 initiator                         :  1,
+		 empty_descriptor                  :  1,
+		 ring_id                           :  8,
+		 looping_count                     :  4;
+};
+
 #define HAL_MON_BUFFER_ADDR_31_0_GET(buff_addr_info)	\
 	(_HAL_MS((*_OFFSET_TO_WORD_PTR(buff_addr_info,	\
 		HAL_BUFFER_ADDR_INFO_BUFFER_ADDR_31_0_OFFSET)),	\
@@ -420,17 +451,25 @@ hal_be_get_mon_dest_status(hal_soc_handle_t hal_soc,
 {
 	struct mon_destination_ring *desc = hw_desc;
 
-	status->buf_addr = HAL_RX_GET(desc, MON_DESTINATION_RING_STAT,
-				      BUF_VIRT_ADDR_31_0) |
-				      (((uint64_t)HAL_RX_GET(desc,
-				      MON_DESTINATION_RING_STAT,
-				      BUF_VIRT_ADDR_63_32)) << 32);
-
+	status->empty_descriptor = desc->empty_descriptor;
+	if (status->empty_descriptor) {
+		struct mon_destination_drop *drop_desc = hw_desc;
+
+		status->buf_addr = 0;
+		status->ppdu_drop_count = drop_desc->ppdu_drop_cnt;
+		status->mpdu_drop_count = drop_desc->mpdu_drop_cnt;
+		status->tlv_drop_count = drop_desc->tlv_drop_cnt;
+		status->end_of_ppdu_dropped = drop_desc->end_of_ppdu_seen;
+	} else {
+		status->buf_addr = HAL_RX_GET(desc, MON_DESTINATION_RING_STAT,BUF_VIRT_ADDR_31_0) |
+						(((uint64_t)HAL_RX_GET(desc,
+								       MON_DESTINATION_RING_STAT,
+								       BUF_VIRT_ADDR_63_32)) << 32);
+		status->end_reason = desc->end_reason;
+		status->end_offset = desc->end_offset;
+	}
 	status->ppdu_id = desc->ppdu_id;
-	status->end_offset = desc->end_offset;
-	status->end_reason = desc->end_reason;
 	status->initiator = desc->initiator;
-	status->empty_descriptor = desc->empty_descriptor;
 	status->looping_count = desc->looping_count;
 }
 #endif