提交 884a963f 编写于 作者: R Rajkumar Manoharan 提交者: John W. Linville

ath9k: fix beacon resource related race condition

The beacon tasklet is accesssing the bslot info for beacon generation.
Meanwhile the same slot can be freed on interface deletion.
Current the remove_interface disables the beacon alert after freeing the slot.
This may leads to null pointer access.

This patch disables SWBA and kills the beacon tasklet to prevent access
to the slot to be freed. After releasing the slot, swba will be enabled again
upon the availablity of beaconing interfaces.
Signed-off-by: NRajkumar Manoharan <rmanoharan@atheros.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 38852b20
...@@ -1520,8 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ...@@ -1520,8 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
struct ath_softc *sc = aphy->sc; struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_vif *avp = (void *)vif->drv_priv; struct ath_vif *avp = (void *)vif->drv_priv;
bool bs_valid = false;
int i;
ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
...@@ -1535,26 +1533,21 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ...@@ -1535,26 +1533,21 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
/* Disable SWBA interrupt */
sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
ath9k_ps_restore(sc); ath9k_ps_restore(sc);
tasklet_kill(&sc->bcon_tasklet);
} }
ath_beacon_return(sc, avp); ath_beacon_return(sc, avp);
sc->sc_flags &= ~SC_OP_BEACONS; sc->sc_flags &= ~SC_OP_BEACONS;
for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { if (sc->nbcnvifs) {
if (sc->beacon.bslot[i] == vif) { /* Re-enable SWBA interrupt */
printk(KERN_DEBUG "%s: vif had allocated beacon " sc->sc_ah->imask |= ATH9K_INT_SWBA;
"slot\n", __func__);
sc->beacon.bslot[i] = NULL;
sc->beacon.bslot_aphy[i] = NULL;
} else if (sc->beacon.bslot[i])
bs_valid = true;
}
if (!bs_valid && (sc->sc_ah->imask & ATH9K_INT_SWBA)) {
/* Disable SWBA interrupt */
sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
ath9k_ps_restore(sc); ath9k_ps_restore(sc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册