diff options
author | Bob Copeland <me@bobcopeland.com> | 2009-06-02 23:03:06 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-06-03 14:06:15 -0400 |
commit | 72828b1b3cabecfce4321877aa526a2bd21acf0c (patch) | |
tree | 2ac007b084ddf9e19ebe97ade778ac9148dac7a0 /drivers/net/wireless/ath | |
parent | 894df1cbc376310163d41c50c891db41296056bf (diff) | |
download | linux-72828b1b3cabecfce4321877aa526a2bd21acf0c.tar.gz linux-72828b1b3cabecfce4321877aa526a2bd21acf0c.tar.bz2 linux-72828b1b3cabecfce4321877aa526a2bd21acf0c.zip |
ath5k: disable beacon interrupt when interface is down
When we remove the active interface, there's no need to continue
sending beacons; doing so would cause a null pointer deref in
ieee80211_beacon_get(). Disable the interrupt in remove_interface
and add a WARN_ON(!vif) in case there are other instances lurking.
Signed-off-by: Bob Copeland <me@bobcopeland.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 | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ab2048b2fa92..85a00db4867d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2070,6 +2070,13 @@ err_unmap: return ret; } +static void ath5k_beacon_disable(struct ath5k_softc *sc) +{ + sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); + ath5k_hw_set_imr(sc->ah, sc->imask); + ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq); +} + /* * Transmit a beacon frame at SWBA. Dynamic updates to the * frame contents are done as needed and the slot time is @@ -2757,6 +2764,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw, goto end; ath5k_hw_set_lladdr(sc->ah, mac); + ath5k_beacon_disable(sc); sc->vif = NULL; end: mutex_unlock(&sc->lock); @@ -3060,7 +3068,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { int ret; struct ath5k_softc *sc = hw->priv; - struct sk_buff *skb = ieee80211_beacon_get(hw, vif); + struct sk_buff *skb; + + if (WARN_ON(!vif)) { + ret = -EINVAL; + goto out; + } + + skb = ieee80211_beacon_get(hw, vif); if (!skb) { ret = -ENOMEM; |