diff options
author | Ming Lei <tom.leiming@gmail.com> | 2010-05-15 06:25:40 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-06-04 14:55:09 -0400 |
commit | ce9426d1908001fb2f7b0152fbe4184bbc0c7b68 (patch) | |
tree | 42389f116a18a2ba8c3d7b20f52d591766bb9602 /drivers/net/wireless/ath/ath9k/recv.c | |
parent | 26b36cfefaf2be98b225e3c1a399edb0daf52ddd (diff) |
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>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/recv.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1618f8fe195d..d373364ef8a9 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -700,12 +700,16 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, | |||
700 | bf = SKB_CB_ATHBUF(skb); | 700 | bf = SKB_CB_ATHBUF(skb); |
701 | BUG_ON(!bf); | 701 | BUG_ON(!bf); |
702 | 702 | ||
703 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | 703 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, |
704 | common->rx_bufsize, DMA_FROM_DEVICE); | 704 | common->rx_bufsize, DMA_FROM_DEVICE); |
705 | 705 | ||
706 | ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); | 706 | ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); |
707 | if (ret == -EINPROGRESS) | 707 | if (ret == -EINPROGRESS) { |
708 | /*let device gain the buffer again*/ | ||
709 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | ||
710 | common->rx_bufsize, DMA_FROM_DEVICE); | ||
708 | return false; | 711 | return false; |
712 | } | ||
709 | 713 | ||
710 | __skb_unlink(skb, &rx_edma->rx_fifo); | 714 | __skb_unlink(skb, &rx_edma->rx_fifo); |
711 | if (ret == -EINVAL) { | 715 | if (ret == -EINVAL) { |
@@ -814,7 +818,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
814 | * 1. accessing the frame | 818 | * 1. accessing the frame |
815 | * 2. requeueing the same buffer to h/w | 819 | * 2. requeueing the same buffer to h/w |
816 | */ | 820 | */ |
817 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | 821 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, |
818 | common->rx_bufsize, | 822 | common->rx_bufsize, |
819 | DMA_FROM_DEVICE); | 823 | DMA_FROM_DEVICE); |
820 | 824 | ||