Commit b3f194e5 authored by Bruno Randolf's avatar Bruno Randolf Committed by John W. Linville

ath5k: clean up rxlink handling

There were a few places where the sc->rxlink pointer was set to NULL "just in
case". This helps nothing - quite to the contrary it is problematic since it
can create self-linked rx descriptors in the middle of the list of receive
buffers.

Here is an example how this could happen (thanks Bob!):

cpu 0:                                      cpu 1:

ath5k_rx_stop
                                            ath5k_tasklet_rx
sc->rxlink = NULL;   /* just in case */
                                              // following doesn't link used
                                              // buffer to prev.
                                              ath5k_rxbuf_setup()

In the case of ath5k_rx_stop() and ath5k_stop_locked() buffers/descriptors are
not changed so rxlink should not be changed as well.

In ath5k_intr() we seem to  try to work around a hardware bug, as the comment
(which is copied 1:1 from the HAL) suggests. I don't see how this could help.
Also the HAL does not set rxlink in this case (So where does this code come
from? It has been there since the first import of ath5k). Changed to just
increment a statistics counter.

After this patch rxlink is only set to NULL before we initialize rx descriptors
and updated when the descriptors are linked together.
Signed-off-by: default avatarBruno Randolf <br1@einfach.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 450464de
...@@ -1728,8 +1728,6 @@ ath5k_rx_stop(struct ath5k_softc *sc) ...@@ -1728,8 +1728,6 @@ ath5k_rx_stop(struct ath5k_softc *sc)
ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */
ath5k_debug_printrxbuffs(sc, ah); ath5k_debug_printrxbuffs(sc, ah);
sc->rxlink = NULL; /* just in case */
} }
static unsigned int static unsigned int
...@@ -2633,8 +2631,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) ...@@ -2633,8 +2631,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
if (!test_bit(ATH_STAT_INVALID, sc->status)) { if (!test_bit(ATH_STAT_INVALID, sc->status)) {
ath5k_rx_stop(sc); ath5k_rx_stop(sc);
ath5k_hw_phy_disable(ah); ath5k_hw_phy_disable(ah);
} else }
sc->rxlink = NULL;
return 0; return 0;
} }
...@@ -2771,7 +2768,7 @@ ath5k_intr(int irq, void *dev_id) ...@@ -2771,7 +2768,7 @@ ath5k_intr(int irq, void *dev_id)
* RXE bit is written, but it doesn't work at * RXE bit is written, but it doesn't work at
* least on older hardware revs. * least on older hardware revs.
*/ */
sc->rxlink = NULL; sc->stats.rxeol_intr++;
} }
if (status & AR5K_INT_TXURN) { if (status & AR5K_INT_TXURN) {
/* bump tx trigger level */ /* bump tx trigger level */
......
...@@ -137,6 +137,7 @@ struct ath5k_statistics { ...@@ -137,6 +137,7 @@ struct ath5k_statistics {
unsigned int mib_intr; unsigned int mib_intr;
unsigned int rxorn_intr; unsigned int rxorn_intr;
unsigned int rxeol_intr;
}; };
#if CHAN_DEBUG #if CHAN_DEBUG
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment