Hi Bob, On Wed, Apr 15, 2009 at 12:57 PM, Bob Copeland <me@xxxxxxxxxxxxxxx> wrote: > 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. Just an observation: Each synchronous read over PCI will take at minimum 0.9us to return. Accessing tables in the host's cache hierarchy/memory will likely be much faster - possibly why it is done like this already. Is this a worthwhile tradeoff? Many thanks, Daniel > Signed-off-by: Bob Copeland <me@xxxxxxxxxxxxxxx> > --- > drivers/net/wireless/ath/ath5k/base.c | 24 ++++-------------------- > drivers/net/wireless/ath/ath5k/base.h | 1 - > 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 3bde18f..1a6e72f 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) > struct sk_buff *skb, *next_skb; > dma_addr_t next_skb_addr; > struct ath5k_softc *sc = (void *)data; > - struct ath5k_buf *bf, *bf_last; > + struct ath5k_buf *bf; > struct ath5k_desc *ds; > int ret; > int hdrlen; > @@ -1791,7 +1791,6 @@ ath5k_tasklet_rx(unsigned long data) > ATH5K_WARN(sc, "empty rx buf pool\n"); > goto unlock; > } > - bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list); > do { > rxs.flag = 0; > > @@ -1800,24 +1799,9 @@ ath5k_tasklet_rx(unsigned long data) > skb = bf->skb; > ds = bf->desc; > > - /* > - * last buffer must not be freed to ensure proper hardware > - * function. When the hardware finishes also a packet next to > - * it, we are sure, it doesn't use it anymore and we can go on. > - */ > - if (bf_last == bf) > - bf->flags |= 1; > - if (bf->flags) { > - struct ath5k_buf *bf_next = list_entry(bf->list.next, > - struct ath5k_buf, list); > - ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc, > - &rs); > - if (ret) > - break; > - bf->flags &= ~1; > - /* skip the overwritten one (even status is martian) */ > - goto next; > - } > + /* bail if HW is still using self-linked descriptor */ > + if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr) > + break; > > ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); > if (unlikely(ret == -EINPROGRESS)) > diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h > index 8229561..852b2c1 100644 > --- a/drivers/net/wireless/ath/ath5k/base.h > +++ b/drivers/net/wireless/ath/ath5k/base.h > @@ -56,7 +56,6 @@ > > struct ath5k_buf { > struct list_head list; > - unsigned int flags; /* rx descriptor flags */ > struct ath5k_desc *desc; /* virtual addr of desc */ > dma_addr_t daddr; /* physical addr of desc */ > 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 b65b4fe..941b511 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) > * ath5k_hw_get_rxdp - Get RX Descriptor's address > * > * @ah: The &struct ath5k_hw > - * > - * XXX: Is RXDP read and clear ? > */ > u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) > { -- Daniel J Blueman -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html