ath9k: fix dma sync in rx path

If buffer is to be accessed by cpu after dma is over, but
between dma mapping and dma unmapping, we should use
dma_sync_single_for_cpu to sync the buffer between cpu with
device. And dma_sync_single_for_device is used to let
device gain the buffer again.

v2: Felix pointed out dma_sync_single_for_device is needed to return
buffer to device if an unsuccessful status bit check is found.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Acked-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Ming Lei 2010-05-15 18:25:40 +08:00 committed by John W. Linville
parent 26b36cfefa
commit ce9426d190

View File

@ -700,12 +700,16 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
bf = SKB_CB_ATHBUF(skb);
BUG_ON(!bf);
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
common->rx_bufsize, DMA_FROM_DEVICE);
ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
if (ret == -EINPROGRESS)
if (ret == -EINPROGRESS) {
/*let device gain the buffer again*/
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
common->rx_bufsize, DMA_FROM_DEVICE);
return false;
}
__skb_unlink(skb, &rx_edma->rx_fifo);
if (ret == -EINVAL) {
@ -814,7 +818,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
* 1. accessing the frame
* 2. requeueing the same buffer to h/w
*/
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
common->rx_bufsize,
DMA_FROM_DEVICE);