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 | |
parent | 894df1cbc376310163d41c50c891db41296056bf (diff) |
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')
-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: | |||
2070 | return ret; | 2070 | return ret; |
2071 | } | 2071 | } |
2072 | 2072 | ||
2073 | static void ath5k_beacon_disable(struct ath5k_softc *sc) | ||
2074 | { | ||
2075 | sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); | ||
2076 | ath5k_hw_set_imr(sc->ah, sc->imask); | ||
2077 | ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq); | ||
2078 | } | ||
2079 | |||
2073 | /* | 2080 | /* |
2074 | * Transmit a beacon frame at SWBA. Dynamic updates to the | 2081 | * Transmit a beacon frame at SWBA. Dynamic updates to the |
2075 | * frame contents are done as needed and the slot time is | 2082 | * frame contents are done as needed and the slot time is |
@@ -2757,6 +2764,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw, | |||
2757 | goto end; | 2764 | goto end; |
2758 | 2765 | ||
2759 | ath5k_hw_set_lladdr(sc->ah, mac); | 2766 | ath5k_hw_set_lladdr(sc->ah, mac); |
2767 | ath5k_beacon_disable(sc); | ||
2760 | sc->vif = NULL; | 2768 | sc->vif = NULL; |
2761 | end: | 2769 | end: |
2762 | mutex_unlock(&sc->lock); | 2770 | mutex_unlock(&sc->lock); |
@@ -3060,7 +3068,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
3060 | { | 3068 | { |
3061 | int ret; | 3069 | int ret; |
3062 | struct ath5k_softc *sc = hw->priv; | 3070 | struct ath5k_softc *sc = hw->priv; |
3063 | struct sk_buff *skb = ieee80211_beacon_get(hw, vif); | 3071 | struct sk_buff *skb; |
3072 | |||
3073 | if (WARN_ON(!vif)) { | ||
3074 | ret = -EINVAL; | ||
3075 | goto out; | ||
3076 | } | ||
3077 | |||
3078 | skb = ieee80211_beacon_get(hw, vif); | ||
3064 | 3079 | ||
3065 | if (!skb) { | 3080 | if (!skb) { |
3066 | ret = -ENOMEM; | 3081 | ret = -ENOMEM; |