瀏覽代碼

qcacmn: Add support to handle BAR frames in host

Due to recent FW changes not filtering out BAR frames, redirect these
frames to REO exception ring and handle as normal data packets.

Change-Id: I4540929fddab14de57a23f6364fc916a70057cbe
CRs-Fixed: 2795499
Saket Jha 4 年之前
父節點
當前提交
af0f724da2

+ 104 - 10
dp/wifi3.0/dp_rx_err.c

@@ -776,9 +776,9 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf,
 }
 
 static
-void dp_rx_wbm_err_handle_bar(struct dp_soc *soc,
-			      struct dp_peer *peer,
-			      qdf_nbuf_t nbuf)
+void dp_rx_err_handle_bar(struct dp_soc *soc,
+			  struct dp_peer *peer,
+			  qdf_nbuf_t nbuf)
 {
 	uint8_t *rx_tlv_hdr;
 	unsigned char type, subtype;
@@ -817,6 +817,76 @@ void dp_rx_wbm_err_handle_bar(struct dp_soc *soc,
 			       start_seq_num);
 }
 
+static void
+dp_rx_bar_frame_handle(struct dp_soc *soc,
+		       hal_ring_desc_t ring_desc,
+		       struct dp_rx_desc *rx_desc,
+		       struct hal_rx_mpdu_desc_info *mpdu_desc_info,
+		       uint8_t error)
+{
+	qdf_nbuf_t nbuf;
+	struct dp_pdev *pdev;
+	struct dp_peer *peer;
+	struct rx_desc_pool *rx_desc_pool;
+	uint16_t peer_id;
+	uint8_t *rx_tlv_hdr;
+	uint32_t tid;
+
+	nbuf = rx_desc->nbuf;
+	rx_desc_pool = &soc->rx_desc_buf[rx_desc->pool_id];
+	dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf,
+					  rx_desc_pool->buf_size,
+					  false);
+	qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf,
+				     QDF_DMA_FROM_DEVICE,
+				     rx_desc_pool->buf_size);
+	rx_desc->unmapped = 1;
+	rx_tlv_hdr = qdf_nbuf_data(nbuf);
+	peer_id =
+		hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc,
+						rx_tlv_hdr);
+	peer = dp_peer_get_ref_by_id(soc, peer_id,
+				     DP_MOD_ID_RX_ERR);
+	tid = hal_rx_mpdu_start_tid_get(soc->hal_soc,
+					rx_tlv_hdr);
+	pdev = dp_get_pdev_for_lmac_id(soc, rx_desc->pool_id);
+
+	if (!peer)
+		goto next;
+
+	dp_info("BAR frame: peer = "QDF_MAC_ADDR_FMT
+		" peer_id = %d"
+		" tid = %u"
+		" SSN = %d"
+		" error status = %d",
+		QDF_MAC_ADDR_REF(peer->mac_addr.raw),
+		peer->peer_id,
+		tid,
+		mpdu_desc_info->mpdu_seq,
+		error);
+
+	switch (error) {
+	case HAL_REO_ERR_BAR_FRAME_2K_JUMP:
+		/* fallthrough */
+	case HAL_REO_ERR_BAR_FRAME_OOR:
+		dp_rx_err_handle_bar(soc, peer, nbuf);
+		DP_STATS_INC(soc,
+			     rx.err.reo_error[error], 1);
+		break;
+	default:
+		DP_STATS_INC(soc, rx.bar_frame, 1);
+	}
+
+	dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
+next:
+	dp_rx_link_desc_return(soc, ring_desc,
+			       HAL_BM_ACTION_PUT_IN_IDLE_LIST);
+	dp_rx_add_to_free_desc_list(&pdev->free_list_head,
+				    &pdev->free_list_tail,
+				    rx_desc);
+	qdf_nbuf_free(nbuf);
+}
+
 /**
  * dp_2k_jump_handle() - Function to handle 2k jump exception
  *                        on WBM ring
@@ -1614,9 +1684,14 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
 
 		error = HAL_RX_ERROR_STATUS_GET(ring_desc);
 
-		qdf_assert(error == HAL_REO_ERROR_DETECTED);
-
 		buf_type = HAL_RX_REO_BUF_TYPE_GET(ring_desc);
+
+		/* Get the MPDU DESC info */
+		hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info);
+
+		if (mpdu_desc_info.msdu_count == 0)
+			goto next_entry;
+
 		/*
 		 * For REO error ring, expect only MSDU LINK DESC
 		 */
@@ -1673,8 +1748,20 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
 
 		mac_id = rx_desc->pool_id;
 
-		/* Get the MPDU DESC info */
-		hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info);
+		if (mpdu_desc_info.bar_frame) {
+			qdf_assert_always(mpdu_desc_info.msdu_count == 1);
+
+			dp_rx_bar_frame_handle(soc,
+					       ring_desc,
+					       rx_desc,
+					       &mpdu_desc_info,
+					       error);
+
+			rx_bufs_reaped[mac_id] += 1;
+			goto next_entry;
+		}
+
+		dp_info("Got pkt with REO ERROR: %d", error);
 
 		if (mpdu_desc_info.mpdu_flags & HAL_MPDU_F_FRAGMENT) {
 			/*
@@ -1725,6 +1812,11 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
 			goto next_entry;
 		}
 
+		/*
+		 * Expect REO errors to be handled after this point
+		 */
+		qdf_assert_always(error == HAL_REO_ERROR_DETECTED);
+
 		if (hal_rx_reo_is_pn_error(ring_desc)) {
 			/* TOD0 */
 			DP_STATS_INC(soc,
@@ -1786,6 +1878,8 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
 			rx_bufs_reaped[mac_id] += count;
 			goto next_entry;
 		}
+		/* Assert if unexpected error type */
+		qdf_assert_always(0);
 next_entry:
 		dp_rx_link_cookie_invalidate(ring_desc);
 		hal_srng_dst_get_next(hal_soc, hal_ring_hdl);
@@ -2151,9 +2245,9 @@ done:
 				case HAL_REO_ERR_BAR_FRAME_2K_JUMP:
 				case HAL_REO_ERR_BAR_FRAME_OOR:
 					if (peer)
-						dp_rx_wbm_err_handle_bar(soc,
-									 peer,
-									 nbuf);
+						dp_rx_err_handle_bar(soc,
+								     peer,
+								     nbuf);
 					qdf_nbuf_free(nbuf);
 					break;
 

+ 4 - 0
dp/wifi3.0/dp_stats.c

@@ -6055,6 +6055,8 @@ void dp_txrx_path_stats(struct dp_soc *soc)
 		DP_PRINT_STATS("hal ring access full fail: %u msdus",
 			       pdev->soc->stats.rx.err.hal_ring_access_full_fail);
 
+		DP_PRINT_STATS("Rx BAR frames:%d", soc->stats.rx.bar_frame);
+
 		for (error_code = 0; error_code < HAL_REO_ERR_MAX;
 				error_code++) {
 			if (!pdev->soc->stats.rx.err.reo_error[error_code])
@@ -6636,6 +6638,8 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
 	DP_PRINT_STATS("REO Error(0-14):%s", reo_error);
 	DP_PRINT_STATS("REO CMD SEND FAIL: %d",
 		       soc->stats.rx.err.reo_cmd_send_fail);
+
+	DP_PRINT_STATS("Rx BAR frames:%d", soc->stats.rx.bar_frame);
 }
 
 #ifdef FEATURE_TSO_STATS

+ 2 - 0
dp/wifi3.0/dp_types.h

@@ -889,6 +889,8 @@ struct dp_soc_stats {
 		uint32_t near_full;
 		/* Break ring reaping as not all scattered msdu received */
 		uint32_t msdu_scatter_wait_break;
+		/* Number of bar frames received */
+		uint32_t bar_frame;
 
 		struct {
 			/* Invalid RBM error count */

+ 9 - 0
hal/wifi3.0/hal_api.h

@@ -1101,6 +1101,15 @@ extern void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
 	 (HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ERROR_ ## \
 	  DESTINATION_RING_ ## _OFFSET ## _SHFT))
 
+/*
+ * Macro to access HWIO_REO_R0_ERROR_DESTINATION_RING_CTRL_IX_1
+ * to map destination to rings
+ */
+#define HAL_REO_ERR_REMAP_IX1(_VALUE, _OFFSET) \
+	((_VALUE) << \
+	 (HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ERROR_ ## \
+	  DESTINATION_RING_ ## _OFFSET ## _SHFT))
+
 /*
  * Macro to access HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0
  * to map destination to rings

+ 8 - 0
hal/wifi3.0/hal_rx.h

@@ -186,12 +186,14 @@ enum hal_rx_msdu_desc_flags {
  *                      [2] AMPDU flag
  *			[3] raw_ampdu
  * @peer_meta_data:	Upper bits containing peer id, vdev id
+ * @bar_frame: indicates if received frame is a bar frame
  */
 struct hal_rx_mpdu_desc_info {
 	uint16_t msdu_count;
 	uint16_t mpdu_seq; /* 12 bits for length */
 	uint32_t mpdu_flags;
 	uint32_t peer_meta_data; /* sw progamed meta-data:MAC Id & peer Id */
+	uint16_t bar_frame;
 };
 
 /**
@@ -427,6 +429,11 @@ enum hal_rx_ret_buf_manager {
 	HAL_RX_MPDU_AMPDU_FLAG_GET(mpdu_info_ptr) |	\
 	HAL_RX_MPDU_RAW_MPDU_GET(mpdu_info_ptr))
 
+#define HAL_RX_MPDU_BAR_FRAME_GET(mpdu_info_ptr) \
+	((mpdu_info_ptr[RX_MPDU_DESC_INFO_0_BAR_FRAME_OFFSET >> 2] & \
+	RX_MPDU_DESC_INFO_0_BAR_FRAME_MASK) >> \
+	RX_MPDU_DESC_INFO_0_BAR_FRAME_LSB)
+
 
 #define HAL_RX_MSDU_PKT_LENGTH_GET(msdu_info_ptr)		\
 	(_HAL_MS((*_OFFSET_TO_WORD_PTR(msdu_info_ptr,		\
@@ -558,6 +565,7 @@ static inline void hal_rx_mpdu_desc_info_get(void *desc_addr,
 	mpdu_desc_info->mpdu_flags = HAL_RX_MPDU_FLAGS_GET(mpdu_info);
 	mpdu_desc_info->peer_meta_data =
 		HAL_RX_MPDU_DESC_PEER_META_DATA_GET(mpdu_info);
+	mpdu_desc_info->bar_frame = HAL_RX_MPDU_BAR_FRAME_GET(mpdu_info);
 }
 
 /*

+ 2 - 2
hal/wifi3.0/qca6390/hal_6390.c

@@ -1027,9 +1027,9 @@ hal_reo_set_err_dst_remap_6390(void *hal_soc)
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 3) |
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 4) |
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 5) |
-		HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 6) |
+		HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 6) |
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 7) |
-		HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 8) |
+		HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 8) |
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 9);
 
 		HAL_REG_WRITE(hal_soc,

+ 11 - 0
hal/wifi3.0/qca6390/hal_6390_rx.h

@@ -294,6 +294,17 @@
 			HWIO_REO_R0_GENERAL_ENABLE_ADDR( \
 			SEQ_WCSS_UMAC_REO_REG_OFFSET), \
 			(reg_val)); \
+		reg_val = \
+			HAL_REG_READ((soc), \
+				     HWIO_REO_R0_GENERAL_ENABLE_ADDR(	\
+				     SEQ_WCSS_UMAC_REO_REG_OFFSET)); \
+		reg_val &= \
+			(~HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_BMSK |\
+				(REO_REMAP_TCL << HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_SHFT)); \
+		HAL_REG_WRITE((soc), \
+			      HWIO_REO_R0_GENERAL_ENABLE_ADDR( \
+			      SEQ_WCSS_UMAC_REO_REG_OFFSET), \
+			      (reg_val)); \
 	} while (0)
 
 #define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \

+ 21 - 1
hal/wifi3.0/qca6490/hal_6490.c

@@ -1471,9 +1471,18 @@ hal_reo_set_err_dst_remap_6490(void *hal_soc)
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 3) |
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 4) |
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 5) |
-		HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 6) |
+		HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 6) |
 		HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 7);
 
+	uint32_t dst_remap_ix1 =
+		HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 14) |
+		HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 13) |
+		HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 12) |
+		HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 11) |
+		HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 10) |
+		HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 9) |
+		HAL_REO_ERR_REMAP_IX1(REO_REMAP_TCL, 8);
+
 		HAL_REG_WRITE(hal_soc,
 			      HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ADDR(
 			      SEQ_WCSS_UMAC_REO_REG_OFFSET),
@@ -1484,6 +1493,17 @@ hal_reo_set_err_dst_remap_6490(void *hal_soc)
 			 hal_soc,
 			 HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ADDR(
 			 SEQ_WCSS_UMAC_REO_REG_OFFSET)));
+
+		HAL_REG_WRITE(hal_soc,
+			      HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ADDR(
+			      SEQ_WCSS_UMAC_REO_REG_OFFSET),
+			      dst_remap_ix1);
+
+		hal_info("HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1 0x%x",
+			 HAL_REG_READ(
+			 hal_soc,
+			 HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ADDR(
+			 SEQ_WCSS_UMAC_REO_REG_OFFSET)));
 }
 
 /**

+ 11 - 0
hal/wifi3.0/qca6490/hal_6490_rx.h

@@ -307,6 +307,17 @@
 			      HWIO_REO_R0_MISC_CTL_ADDR( \
 			      SEQ_WCSS_UMAC_REO_REG_OFFSET), \
 			      (reg_val)); \
+		reg_val = \
+			HAL_REG_READ((soc), \
+				     HWIO_REO_R0_GENERAL_ENABLE_ADDR(	\
+				     SEQ_WCSS_UMAC_REO_REG_OFFSET)); \
+		reg_val &= \
+			(~HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_BMSK |\
+				(REO_REMAP_TCL << HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_SHFT)); \
+		HAL_REG_WRITE((soc), \
+			      HWIO_REO_R0_GENERAL_ENABLE_ADDR( \
+			      SEQ_WCSS_UMAC_REO_REG_OFFSET), \
+			      (reg_val)); \
 	} while (0)
 
 #define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \