diff options
author | Bob Copeland <me@bobcopeland.com> | 2009-04-15 07:57:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-04-22 16:57:14 -0400 |
commit | c57ca81576e7ca0369ea52c9ac5f35d0f6ca1270 (patch) | |
tree | c121d33c69a2eccf0658c7f7953d6eb9435c8d44 /drivers/net/wireless/ath/ath5k/base.c | |
parent | 46802a4f07cd2367d584bb1a2e6998d22d4d4f3a (diff) |
ath5k: use rx hw descriptor pointer for self-linked check
This patch simplifies the code used to detect when the
self-linked DMA buffer is still in use by hardware, by
checking the hardware's rxdp register instead of looking
at the software buffer list.
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Acked-by: Nick Kossifidis <mickflemm@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 24 |
1 files changed, 4 insertions, 20 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 3bde18f91450..1a6e72fe7be9 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1780,7 +1780,7 @@ ath5k_tasklet_rx(unsigned long data) | |||
1780 | struct sk_buff *skb, *next_skb; | 1780 | struct sk_buff *skb, *next_skb; |
1781 | dma_addr_t next_skb_addr; | 1781 | dma_addr_t next_skb_addr; |
1782 | struct ath5k_softc *sc = (void *)data; | 1782 | struct ath5k_softc *sc = (void *)data; |
1783 | struct ath5k_buf *bf, *bf_last; | 1783 | struct ath5k_buf *bf; |
1784 | struct ath5k_desc *ds; | 1784 | struct ath5k_desc *ds; |
1785 | int ret; | 1785 | int ret; |
1786 | int hdrlen; | 1786 | int hdrlen; |
@@ -1791,7 +1791,6 @@ ath5k_tasklet_rx(unsigned long data) | |||
1791 | ATH5K_WARN(sc, "empty rx buf pool\n"); | 1791 | ATH5K_WARN(sc, "empty rx buf pool\n"); |
1792 | goto unlock; | 1792 | goto unlock; |
1793 | } | 1793 | } |
1794 | bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list); | ||
1795 | do { | 1794 | do { |
1796 | rxs.flag = 0; | 1795 | rxs.flag = 0; |
1797 | 1796 | ||
@@ -1800,24 +1799,9 @@ ath5k_tasklet_rx(unsigned long data) | |||
1800 | skb = bf->skb; | 1799 | skb = bf->skb; |
1801 | ds = bf->desc; | 1800 | ds = bf->desc; |
1802 | 1801 | ||
1803 | /* | 1802 | /* bail if HW is still using self-linked descriptor */ |
1804 | * last buffer must not be freed to ensure proper hardware | 1803 | if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr) |
1805 | * function. When the hardware finishes also a packet next to | 1804 | break; |
1806 | * it, we are sure, it doesn't use it anymore and we can go on. | ||
1807 | */ | ||
1808 | if (bf_last == bf) | ||
1809 | bf->flags |= 1; | ||
1810 | if (bf->flags) { | ||
1811 | struct ath5k_buf *bf_next = list_entry(bf->list.next, | ||
1812 | struct ath5k_buf, list); | ||
1813 | ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc, | ||
1814 | &rs); | ||
1815 | if (ret) | ||
1816 | break; | ||
1817 | bf->flags &= ~1; | ||
1818 | /* skip the overwritten one (even status is martian) */ | ||
1819 | goto next; | ||
1820 | } | ||
1821 | 1805 | ||
1822 | ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); | 1806 | ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); |
1823 | if (unlikely(ret == -EINPROGRESS)) | 1807 | if (unlikely(ret == -EINPROGRESS)) |