Преглед на файлове

qcacmn: Do not re-init rx_tid for non-first link peer

As per the current design, the rx_tids are shared across
all the link peers belonging to the same MLD. The rx_tids
are allocated and referenced from txrx_peer, which is common
for all the link peers.

But during the peer_setup, which happens during the initial
connection or during link switch, these rx_tids are being
initialized(or reinitialized) every time for each link peer.

This leads to a situation where:
1) The rx_tids may get re-initialized during the 2nd/3rd/subsequent
link peer setup, even after the BA session has been established via
the first link, thereby setting incorrect BA window size and other
BA parameters for all the non-first link peers. Even the BA session
status will be reset, which can lead to issues for fragmented packets
aggregation.

2) After link switch, when the new link peer is setup, it will be
setup with a default BA window size of 1, when the actual BA window
size has already been established earlier, thereby indicating
an incorrect BA window size for the switched-in link peer.

In order to mitigate the above mentioned issues, the full setup
of tids will only be done for first link peer. For all subsequent
link peers, only the re-order queue setup (wmi notification to fw)
will be done. Also, during the re-order queue setup for all the
non-first link peers, the BA window size will be updated from the
rx_tids in txrx_peer (if the BA session is active).

Change-Id: Ia3f7516ba6efd1014648ead1730712834f450c42
CRs-Fixed: 3657693
Rakesh Pillai преди 1 година
родител
ревизия
f7d4e2a300
променени са 4 файла, в които са добавени 80 реда и са изтрити 2 реда
  1. 22 0
      dp/wifi3.0/dp_internal.h
  2. 56 0
      dp/wifi3.0/dp_peer.c
  3. 1 1
      dp/wifi3.0/dp_rings_main.c
  4. 1 1
      dp/wifi3.0/dp_rx_tid.c

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

@@ -2723,6 +2723,17 @@ void dp_peer_ppdu_delayed_ba_cleanup(struct dp_peer *peer);
  */
 void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer);
 
+/**
+ * dp_peer_rx_init_wrapper() - Initialize receive TID state, based on peer type
+ * @pdev: Datapath pdev
+ * @peer: Datapath peer
+ * @setup_info: setup info received for setting up the peer
+ *
+ * Return: None
+ */
+void dp_peer_rx_init_wrapper(struct dp_pdev *pdev, struct dp_peer *peer,
+			     struct cdp_peer_setup_info *setup_info);
+
 /**
  * dp_peer_cleanup() - Cleanup peer information
  * @vdev: Datapath vdev
@@ -5890,4 +5901,15 @@ void dp_ssr_dump_pdev_unregister(uint8_t pdev_id)
 {
 }
 #endif
+
+/**
+ * dp_get_peer_vdev_roaming_in_progress() - Check if peer's vdev is in roaming
+ *					    state.
+ * @peer: DP peer handle
+ *
+ * Return: true if the peer's vdev is in roaming state
+ *	   else false.
+ */
+bool dp_get_peer_vdev_roaming_in_progress(struct dp_peer *peer);
+
 #endif /* #ifndef _DP_INTERNAL_H_ */

+ 56 - 0
dp/wifi3.0/dp_peer.c

@@ -3245,6 +3245,62 @@ void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer)
 				cdp_sec_type_none;
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static void dp_peer_rx_init_reorder_queue(struct dp_pdev *pdev,
+					  struct dp_peer *peer)
+{
+	struct dp_soc *soc = pdev->soc;
+	struct dp_peer *mld_peer = DP_GET_MLD_PEER_FROM_PEER(peer);
+	struct dp_rx_tid *rx_tid = NULL;
+	uint32_t ba_window_size, tid;
+	QDF_STATUS status;
+
+	if (dp_get_peer_vdev_roaming_in_progress(peer))
+		return;
+
+	tid = DP_NON_QOS_TID;
+	rx_tid = &mld_peer->rx_tid[tid];
+	ba_window_size = rx_tid->ba_status == DP_RX_BA_ACTIVE ?
+					rx_tid->ba_win_size : 1;
+	status = dp_peer_rx_reorder_queue_setup(soc, peer, tid, ba_window_size);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		dp_info("peer %pK " QDF_MAC_ADDR_FMT " type %d failed to setup tid %d ba_win_size %d",
+			peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw),
+			peer->peer_type, tid, ba_window_size);
+		/* Do not return, continue for other tids. */
+	}
+
+	for (tid = 0; tid < DP_MAX_TIDS - 1; tid++) {
+		rx_tid = &mld_peer->rx_tid[tid];
+		ba_window_size = rx_tid->ba_status == DP_RX_BA_ACTIVE ?
+						rx_tid->ba_win_size : 1;
+		status = dp_peer_rx_reorder_queue_setup(soc, peer,
+							tid, ba_window_size);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			dp_info("peer %pK " QDF_MAC_ADDR_FMT " type %d failed to setup tid %d ba_win_size %d",
+				peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw),
+				peer->peer_type, tid, ba_window_size);
+			/* Do not return, continue for other tids. */
+		}
+	}
+}
+
+void dp_peer_rx_init_wrapper(struct dp_pdev *pdev, struct dp_peer *peer,
+			     struct cdp_peer_setup_info *setup_info)
+{
+	if (setup_info && !setup_info->is_first_link)
+		dp_peer_rx_init_reorder_queue(pdev, peer);
+	else
+		dp_peer_rx_init(pdev, peer);
+}
+#else
+void dp_peer_rx_init_wrapper(struct dp_pdev *pdev, struct dp_peer *peer,
+			     struct cdp_peer_setup_info *setup_info)
+{
+	dp_peer_rx_init(pdev, peer);
+}
+#endif
+
 void dp_peer_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
 {
 	enum wlan_op_mode vdev_opmode;

+ 1 - 1
dp/wifi3.0/dp_rings_main.c

@@ -2686,7 +2686,7 @@ dp_peer_setup_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 					dp_peer_err("MLD peer null. Primary link peer:%pK", peer);
 			}
 		} else {
-			dp_peer_rx_init(pdev, peer);
+			dp_peer_rx_init_wrapper(pdev, peer, setup_info);
 		}
 	}
 

+ 1 - 1
dp/wifi3.0/dp_rx_tid.c

@@ -275,7 +275,7 @@ static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt,
 	}
 }
 
-static bool dp_get_peer_vdev_roaming_in_progress(struct dp_peer *peer)
+bool dp_get_peer_vdev_roaming_in_progress(struct dp_peer *peer)
 {
 	struct ol_if_ops *ol_ops = NULL;
 	bool is_roaming = false;