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 | |
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')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/dma.c | 2 |
3 files changed, 4 insertions, 23 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)) |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 822956114cd7..852b2c189fd8 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -56,7 +56,6 @@ | |||
56 | 56 | ||
57 | struct ath5k_buf { | 57 | struct ath5k_buf { |
58 | struct list_head list; | 58 | struct list_head list; |
59 | unsigned int flags; /* rx descriptor flags */ | ||
60 | struct ath5k_desc *desc; /* virtual addr of desc */ | 59 | struct ath5k_desc *desc; /* virtual addr of desc */ |
61 | dma_addr_t daddr; /* physical addr of desc */ | 60 | dma_addr_t daddr; /* physical addr of desc */ |
62 | struct sk_buff *skb; /* skbuff for buf */ | 61 | struct sk_buff *skb; /* skbuff for buf */ |
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index b65b4feb2d28..941b51130a6f 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c | |||
@@ -80,8 +80,6 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) | |||
80 | * ath5k_hw_get_rxdp - Get RX Descriptor's address | 80 | * ath5k_hw_get_rxdp - Get RX Descriptor's address |
81 | * | 81 | * |
82 | * @ah: The &struct ath5k_hw | 82 | * @ah: The &struct ath5k_hw |
83 | * | ||
84 | * XXX: Is RXDP read and clear ? | ||
85 | */ | 83 | */ |
86 | u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) | 84 | u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) |
87 | { | 85 | { |