Skip to content

Commit

Permalink
Ath5k: lock beacons
Browse files Browse the repository at this point in the history
Beacons setup and config was racy with beacon send. Ensure that
ISR and reset functions see consistent state of bbuf.

Use also dev_kfree_skb_any in ath5k_txbuf_free since we call it
from atomic now.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Nick Kossifidis <mickflemm@gmail.com>
Cc: Luis R. Rodriguez <mcgrof@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Jiri Slaby authored and John W. Linville committed Aug 27, 2008
1 parent d0c2912 commit 0048297
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
15 changes: 12 additions & 3 deletions drivers/net/wireless/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
return;
pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
PCI_DMA_TODEVICE);
dev_kfree_skb(bf->skb);
dev_kfree_skb_any(bf->skb);
bf->skb = NULL;
}

Expand Down Expand Up @@ -466,6 +466,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
mutex_init(&sc->lock);
spin_lock_init(&sc->rxbuflock);
spin_lock_init(&sc->txbuflock);
spin_lock_init(&sc->block);

/* Set private data */
pci_set_drvdata(pdev, hw);
Expand Down Expand Up @@ -2179,8 +2180,11 @@ ath5k_beacon_config(struct ath5k_softc *sc)

sc->imask |= AR5K_INT_SWBA;

if (ath5k_hw_hasveol(ah))
if (ath5k_hw_hasveol(ah)) {
spin_lock(&sc->block);
ath5k_beacon_send(sc);
spin_unlock(&sc->block);
}
}
/* TODO else AP */

Expand Down Expand Up @@ -2403,7 +2407,9 @@ ath5k_intr(int irq, void *dev_id)
TSF_TO_TU(tsf),
(unsigned long long) tsf);
} else {
spin_lock(&sc->block);
ath5k_beacon_send(sc);
spin_unlock(&sc->block);
}
}
if (status & AR5K_INT_RXEOL) {
Expand Down Expand Up @@ -3050,6 +3056,7 @@ static int
ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ath5k_softc *sc = hw->priv;
unsigned long flags;
int ret;

ath5k_debug_dump_skb(sc, skb, "BC ", 1);
Expand All @@ -3059,12 +3066,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
goto end;
}

spin_lock_irqsave(&sc->block, flags);
ath5k_txbuf_free(sc, sc->bbuf);
sc->bbuf->skb = skb;
ret = ath5k_beacon_setup(sc, sc->bbuf);
if (ret)
sc->bbuf->skb = NULL;
else {
spin_unlock_irqrestore(&sc->block, flags);
if (!ret) {
ath5k_beacon_config(sc);
mmiowb();
}
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath5k/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ struct ath5k_softc {
struct tasklet_struct txtq; /* tx intr tasklet */
struct ath5k_led tx_led; /* tx led */

spinlock_t block; /* protects beacon */
struct ath5k_buf *bbuf; /* beacon buffer */
unsigned int bhalq, /* SW q for outgoing beacons */
bmisscount, /* missed beacon transmits */
Expand Down

0 comments on commit 0048297

Please sign in to comment.