From b5955f0e24cd18880877c55c6208704e5be98727 Mon Sep 17 00:00:00 2001 From: Lin Bai Date: Tue, 22 May 2018 20:02:19 +0800 Subject: [PATCH] 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 --- dp/wifi3.0/dp_rx_defrag.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index 89117178191e..f2a63a654813 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/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); }