Эх сурвалжийг харах

qcacmn: Handle BAR OOR/2K_JUMP REO errors

Currently in dp_rx_wbm_err_process, we donot handle
HAL_REO_ERR_BAR_FRAME_2K_JUMP and HAL_REO_ERR_BAR_FRAME_OOR REO errors.
Add support for the same.

Change-Id: I22147fcd2d531c1e08214626796994593ffeb3a6
CRs-Fixed: 2580876
Mohit Khanna 5 жил өмнө
parent
commit
82382b32e9

+ 12 - 0
dp/wifi3.0/dp_internal.h

@@ -1669,4 +1669,16 @@ dp_get_pdev_from_soc_pdev_id_wifi3(struct dp_soc *soc,
 	return soc->pdev_list[pdev_id];
 }
 
+/*
+ * dp_rx_tid_update_wifi3() – Update receive TID state
+ * @peer: Datapath peer handle
+ * @tid: TID
+ * @ba_window_size: BlockAck window size
+ * @start_seq: Starting sequence number
+ *
+ * Return: QDF_STATUS code
+ */
+QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
+					 ba_window_size, uint32_t start_seq);
+
 #endif /* #ifndef _DP_INTERNAL_H_ */

+ 1 - 10
dp/wifi3.0/dp_peer.c

@@ -1726,16 +1726,7 @@ static bool dp_get_peer_vdev_roaming_in_progress(struct dp_peer *peer)
 	return is_roaming;
 }
 
-/*
- * dp_rx_tid_update_wifi3() – Update receive TID state
- * @peer: Datapath peer handle
- * @tid: TID
- * @ba_window_size: BlockAck window size
- * @start_seq: Starting sequence number
- *
- * Return: QDF_STATUS code
- */
-static QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
+QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
 					 ba_window_size, uint32_t start_seq)
 {
 	struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];

+ 60 - 4
dp/wifi3.0/dp_rx_err.c

@@ -498,6 +498,49 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr,
 	return mpdu_done;
 }
 
+static
+void dp_rx_wbm_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;
+	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 +
+					     sizeof(struct rx_pkt_tlvs));
+
+	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);
+
+	dp_rx_tid_update_wifi3(peer, tid,
+			       peer->rx_tid[tid].ba_win_size,
+			       start_seq_num);
+}
+
 /**
  * dp_2k_jump_handle() - Function to handle 2k jump exception
  *                        on WBM ring
@@ -1462,16 +1505,21 @@ done:
 		uint8_t *tlv_hdr;
 		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_find_by_id(soc, peer_id);
-
 		/*
 		 * retrieve the wbm desc info from nbuf TLV, so we can
 		 * handle error cases appropriately
 		 */
 		hal_rx_wbm_err_info_get_from_tlv(rx_tlv_hdr, &wbm_err_info);
 
+		peer_id = hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc,
+							   rx_tlv_hdr);
+		peer = dp_peer_find_by_id(soc, peer_id);
+
+		if (!peer)
+			dp_err_rl("peer is null! peer_id %u err_src %u err_rsn %u",
+				  peer_id, wbm_err_info.wbm_err_src,
+				  wbm_err_info.reo_psh_rsn);
+
 		/* Set queue_mapping in nbuf to 0 */
 		dp_set_rx_queue(nbuf, 0);
 
@@ -1526,6 +1574,14 @@ done:
 						dp_peer_unref_del_find_by_id(
 									peer);
 					continue;
+				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);
+					break;
+
 				default:
 					dp_err_rl("Got pkt with REO ERROR: %d",
 						  wbm_err_info.reo_err_code);