فهرست منبع

qcacmn: BAR frame handling for 2K-jump and & OOR error

Currently the detection of whether a frame arriving on the
rx-error ring is done via the flags in the ring descriptor.
For targets which support providing previous PN in the
rx-error ring descriptor, the flags indicating BAR frame
will not be present in the ring descriptor.

Add BAR frame check and handling in the OOR and 2K-jump
frame processing handlers.

Change-Id: Iaba763559a84f1c1f6a193e01945124f08c506f2
CRs-Fixed: 2965086
Rakesh Pillai 4 سال پیش
والد
کامیت
e28d968b5a
1فایلهای تغییر یافته به همراه109 افزوده شده و 85 حذف شده
  1. 109 85
      dp/wifi3.0/dp_rx_err.c

+ 109 - 85
dp/wifi3.0/dp_rx_err.c

@@ -536,6 +536,107 @@ dp_rx_err_nbuf_pn_check(struct dp_soc *soc, hal_ring_desc_t ring_desc,
 	return QDF_STATUS_E_FAILURE;
 }
 
+static
+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;
+	uint16_t start_seq_num;
+	uint32_t tid;
+	QDF_STATUS status;
+	struct ieee80211_frame_bar *bar;
+
+	/*
+	 * 1. Is this a BAR frame. If not Discard it.
+	 * 2. If it is, get the peer id, tid, ssn
+	 * 2a Do a tid update
+	 */
+
+	rx_tlv_hdr = qdf_nbuf_data(nbuf);
+	bar = (struct ieee80211_frame_bar *)(rx_tlv_hdr + soc->rx_pkt_tlv_size);
+
+	type = bar->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+	subtype = bar->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+	if (!(type == IEEE80211_FC0_TYPE_CTL &&
+	      subtype == QDF_IEEE80211_FC0_SUBTYPE_BAR)) {
+		dp_err_rl("Not a BAR frame!");
+		return;
+	}
+
+	tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, rx_tlv_hdr);
+	qdf_assert_always(tid < DP_MAX_TIDS);
+
+	start_seq_num = le16toh(bar->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
+
+	dp_info_rl("tid %u window_size %u start_seq_num %u",
+		   tid, peer->rx_tid[tid].ba_win_size, start_seq_num);
+
+	status = dp_rx_tid_update_wifi3(peer, tid,
+					peer->rx_tid[tid].ba_win_size,
+					start_seq_num);
+	if (status != QDF_STATUS_SUCCESS) {
+		dp_err_rl("failed to handle bar frame update rx tid");
+		DP_STATS_INC(soc, rx.err.bar_handle_fail_count, 1);
+	} else {
+		DP_STATS_INC(soc, rx.err.ssn_update_count, 1);
+	}
+}
+
+/**
+ * _dp_rx_bar_frame_handle(): Core of the BAR frame handling
+ * @soc: Datapath SoC handle
+ * @nbuf: packet being processed
+ * @mpdu_desc_info: mpdu desc info for the current packet
+ * @tid: tid on which the packet arrived
+ * @err_status: Flag to indicate if REO encountered an error while routing this
+ *		frame
+ * @error_code: REO error code
+ *
+ * Return: None
+ */
+static void
+_dp_rx_bar_frame_handle(struct dp_soc *soc, qdf_nbuf_t nbuf,
+			struct hal_rx_mpdu_desc_info *mpdu_desc_info,
+			uint32_t tid, uint8_t err_status, uint32_t error_code)
+{
+	uint16_t peer_id;
+	struct dp_peer *peer;
+
+	peer_id = DP_PEER_METADATA_PEER_ID_GET(mpdu_desc_info->peer_meta_data);
+	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_RX_ERR);
+	if (!peer)
+		return;
+
+	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,
+		err_status);
+
+	if (err_status == HAL_REO_ERROR_DETECTED) {
+		switch (error_code) {
+		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_code], 1);
+			break;
+		default:
+			DP_STATS_INC(soc, rx.bar_frame, 1);
+		}
+	}
+
+	dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
+}
+
 /**
  * dp_rx_reo_err_entry_process() - Handles for REO error entry processing
  *
@@ -656,6 +757,12 @@ more_msdu_link_desc:
 							   mpdu_desc_info);
 			peer_id = DP_PEER_METADATA_PEER_ID_GET(
 					mpdu_desc_info->peer_meta_data);
+
+			if (mpdu_desc_info->bar_frame)
+				_dp_rx_bar_frame_handle(soc, nbuf,
+							mpdu_desc_info, tid,
+							HAL_REO_ERROR_DETECTED,
+							err_code);
 		}
 
 		switch (err_code) {
@@ -830,55 +937,6 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf,
 	return mpdu_done;
 }
 
-static
-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;
-	uint16_t start_seq_num;
-	uint32_t tid;
-	QDF_STATUS status;
-	struct ieee80211_frame_bar *bar;
-
-	/*
-	 * 1. Is this a BAR frame. If not Discard it.
-	 * 2. If it is, get the peer id, tid, ssn
-	 * 2a Do a tid update
-	 */
-
-	rx_tlv_hdr = qdf_nbuf_data(nbuf);
-	bar = (struct ieee80211_frame_bar *)(rx_tlv_hdr + soc->rx_pkt_tlv_size);
-
-	type = bar->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
-	subtype = bar->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
-
-	if (!(type == IEEE80211_FC0_TYPE_CTL &&
-	      subtype == QDF_IEEE80211_FC0_SUBTYPE_BAR)) {
-		dp_err_rl("Not a BAR frame!");
-		return;
-	}
-
-	tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, rx_tlv_hdr);
-	qdf_assert_always(tid < DP_MAX_TIDS);
-
-	start_seq_num = le16toh(bar->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
-
-	dp_info_rl("tid %u window_size %u start_seq_num %u",
-		   tid, peer->rx_tid[tid].ba_win_size, start_seq_num);
-
-	status = dp_rx_tid_update_wifi3(peer, tid,
-					peer->rx_tid[tid].ba_win_size,
-					start_seq_num);
-	if (status != QDF_STATUS_SUCCESS) {
-		dp_err_rl("failed to handle bar frame update rx tid");
-		DP_STATS_INC(soc, rx.err.bar_handle_fail_count, 1);
-	} else {
-		DP_STATS_INC(soc, rx.err.ssn_update_count, 1);
-	}
-}
-
 /**
  * dp_rx_bar_frame_handle() - Function to handle err BAR frames
  * @soc: core DP main context
@@ -904,9 +962,7 @@ dp_rx_bar_frame_handle(struct dp_soc *soc,
 {
 	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;
 
@@ -922,44 +978,12 @@ dp_rx_bar_frame_handle(struct dp_soc *soc,
 	rx_desc->unmapped = 1;
 	dp_ipa_rx_buf_smmu_mapping_unlock(soc);
 	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 code = %d",
-		QDF_MAC_ADDR_REF(peer->mac_addr.raw),
-		peer->peer_id,
-		tid,
-		mpdu_desc_info->mpdu_seq,
-		err_code);
-
-	if (err_status == HAL_REO_ERROR_DETECTED) {
-		switch (err_code) {
-		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[err_code], 1);
-			break;
-		default:
-			DP_STATS_INC(soc, rx.bar_frame, 1);
-		}
-	}
-
-	dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
-next:
+	_dp_rx_bar_frame_handle(soc, nbuf, mpdu_desc_info, tid, err_status,
+				err_code);
 	dp_rx_link_desc_return(soc, ring_desc,
 			       HAL_BM_ACTION_PUT_IN_IDLE_LIST);
 	dp_rx_buffer_pool_nbuf_free(soc, rx_desc->nbuf,