From 5ed83c47b4d4cbb4a42065613a2df465221b86d8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 13 Mar 2015 06:50:13 +0100 Subject: [PATCH] dma: do not check the DMA_DONE bit for tx, use the dma index register instead Signed-off-by: Felix Fietkau --- dma.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/dma.c b/dma.c index c1289a52..84052e02 100644 --- a/dma.c +++ b/dma.c @@ -20,6 +20,12 @@ struct mt76_txwi_cache { struct list_head list; }; +enum mt76_dma_dequeue { + DMA_DEQUEUE_FLUSH, + DMA_DEQUEUE_DDONE, + DMA_DEQUEUE_IDX, +}; + static inline int mt76_rx_buf_offset(struct mt76_dev *dev) { @@ -261,16 +267,31 @@ free: } static int -mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush) +mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, enum mt76_dma_dequeue type) { int ret = -1; + u16 idx; + bool skip; spin_lock_bh(&q->lock); if (!q->queued) goto out; - if (!flush && !(q->desc[q->tail].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE))) + switch (type) { + case DMA_DEQUEUE_DDONE: + skip = !(q->desc[q->tail].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)); + break; + case DMA_DEQUEUE_IDX: + idx = ioread32(&q->regs->dma_idx); + skip = (q->tail == idx); + break; + case DMA_DEQUEUE_FLUSH: + skip = false; + break; + } + + if (skip) goto out; ret = q->tail; @@ -321,10 +342,11 @@ mt76_tx_cleanup_entry(struct mt76_dev *dev, struct mt76_queue *q, int idx, static void mt76_tx_cleanup_queue(struct mt76_dev *dev, struct mt76_queue *q, bool flush) { + enum mt76_dma_dequeue type = flush ? DMA_DEQUEUE_FLUSH : DMA_DEQUEUE_IDX; int idx; do { - idx = mt76_dma_dequeue(dev, q, flush); + idx = mt76_dma_dequeue(dev, q, type); if (idx < 0) break; @@ -359,7 +381,7 @@ mt76_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q) int idx; do { - idx = mt76_dma_dequeue(dev, q, true); + idx = mt76_dma_dequeue(dev, q, DMA_DEQUEUE_FLUSH); if (idx < 0) break; @@ -425,7 +447,7 @@ mt76_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q, int budget) int done = 0; while (done < budget) { - idx = mt76_dma_dequeue(dev, q, false); + idx = mt76_dma_dequeue(dev, q, DMA_DEQUEUE_DDONE); if (idx < 0) break;