[PATCH 3/3] Fix TX stall in case ring is completely full

Eugene Krasnikov k.eugene.e at gmail.com
Thu Jul 18 12:58:47 EDT 2013


In the situation when tx ring is completely full head and tail
are pointing to the same element. Next dxe tx complete interrupt
will not take any element from the ring because it will think
that ring is empty. As a workaround for each dxe tx complete
interrupt take at least one item from the ring.

Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
---
 dxe.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/dxe.c b/dxe.c
index 502e0df..ccdcf2c 100644
--- a/dxe.c
+++ b/dxe.c
@@ -320,9 +320,12 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
 	struct wcn36xx_dxe_ctl *ctl = ch->tail_blk_ctl;
 	struct ieee80211_tx_info *info;
 	unsigned long flags;
-
-	while (ctl != ch->head_blk_ctl &&
-	       !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) {
+	/*
+	 * Make at least one loop of do-while because in case ring is
+	 * completely full head and tail are pointing to the same element
+	 * and while-do will not make any cycles.
+	 */
+	do {
 		if (ctl->skb) {
 			dma_unmap_single(NULL, ctl->desc->src_addr_l,
 					 ctl->skb->len, DMA_TO_DEVICE);
@@ -341,7 +344,8 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
 			ctl->skb = NULL;
 		}
 		ctl = ctl->next;
-	}
+	} while (ctl != ch->head_blk_ctl &&
+	       !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK));
 	ch->tail_blk_ctl = ctl;
 }
 static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
-- 
1.8.2.2




More information about the wcn36xx mailing list