Răsfoiți Sursa

qcacmn: check peer when removing from defrag waitlist

Different peer may use same TID to receive fragment msdu. To avoid
such mismatch, compare both peer and TID number when removing entry
from defrag's waitlist.

CRs-Fixed: 2246558
Change-Id: I80d81e4fa8bef3df429c2a28f2e50135e7fd225f
Lin Bai 6 ani în urmă
părinte
comite
b5955f0e24
1 a modificat fișierele cu 22 adăugiri și 11 ștergeri
  1. 22 11
      dp/wifi3.0/dp_rx_defrag.c

+ 22 - 11
dp/wifi3.0/dp_rx_defrag.c

@@ -105,9 +105,11 @@ void dp_rx_reorder_flush_frag(struct dp_peer *peer,
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 				FL("Flushing TID %d"), tid);
 
-	if (peer == NULL)
+	if (!peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 					"%s: NULL peer\n", __func__);
+		return;
+	}
 
 	pdev = peer->vdev->pdev;
 	soc = pdev->soc;
@@ -145,13 +147,13 @@ void dp_rx_reorder_flush_frag(struct dp_peer *peer,
  */
 void dp_rx_defrag_waitlist_flush(struct dp_soc *soc)
 {
-	struct dp_rx_tid *rx_reorder, *tmp;
+	struct dp_rx_tid *rx_reorder;
+	struct dp_rx_tid *tmp;
 	uint32_t now_ms = qdf_system_ticks_to_msecs(qdf_system_ticks());
 
 	TAILQ_FOREACH_SAFE(rx_reorder, &soc->rx.defrag.waitlist,
 			   defrag_waitlist_elem, tmp) {
 		struct dp_peer *peer;
-		struct dp_rx_tid *rx_reorder_base;
 		unsigned int tid;
 
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
@@ -167,15 +169,14 @@ void dp_rx_defrag_waitlist_flush(struct dp_soc *soc)
 			qdf_assert(0);
 			continue;
 		}
-		/* get index 0 of the rx_reorder array */
-		rx_reorder_base = rx_reorder - tid;
+
+		/* get address of current peer */
 		peer =
-			container_of(rx_reorder_base, struct dp_peer,
-				     rx_tid[0]);
+			container_of(rx_reorder, struct dp_peer,
+				     rx_tid[tid]);
 
 		TAILQ_REMOVE(&soc->rx.defrag.waitlist, rx_reorder,
 			     defrag_waitlist_elem);
-		//dp_rx_defrag_waitlist_remove(peer, tid);
 		dp_rx_reorder_flush_frag(peer, tid);
 	}
 }
@@ -195,7 +196,8 @@ static void dp_rx_defrag_waitlist_add(struct dp_peer *peer, unsigned tid)
 	struct dp_rx_tid *rx_reorder = &peer->rx_tid[tid];
 
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-				FL("Adding TID %u to waitlist"), tid);
+				FL("Adding TID %u to waitlist for peer %pK"),
+				tid, peer);
 
 	/* TODO: use LIST macros instead of TAIL macros */
 	TAILQ_INSERT_TAIL(&psoc->rx.defrag.waitlist, rx_reorder,
@@ -225,11 +227,20 @@ void dp_rx_defrag_waitlist_remove(struct dp_peer *peer, unsigned tid)
 	}
 
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-				FL("Remove TID %u from waitlist"), tid);
+				FL("Remove TID %u from waitlist for peer %pK"),
+				tid, peer);
 
 	TAILQ_FOREACH(rx_reorder, &soc->rx.defrag.waitlist,
 			   defrag_waitlist_elem) {
-		if (rx_reorder->tid == tid)
+		struct dp_peer *peer_on_waitlist;
+
+		/* get address of current peer */
+		peer_on_waitlist =
+			container_of(rx_reorder, struct dp_peer,
+				     rx_tid[rx_reorder->tid]);
+
+		/* Ensure it is TID for same peer */
+		if (peer_on_waitlist == peer && rx_reorder->tid == tid)
 			TAILQ_REMOVE(&soc->rx.defrag.waitlist,
 				rx_reorder, defrag_waitlist_elem);
 	}