|
@@ -345,7 +345,7 @@ void ath9k_tasklet(unsigned long data)
|
|
|
struct ath_softc *sc = (struct ath_softc *)data;
|
|
|
struct ath_hw *ah = sc->sc_ah;
|
|
|
struct ath_common *common = ath9k_hw_common(ah);
|
|
|
-
|
|
|
+ unsigned long flags;
|
|
|
u32 status = sc->intrstatus;
|
|
|
u32 rxmask;
|
|
|
|
|
@@ -369,6 +369,7 @@ void ath9k_tasklet(unsigned long data)
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
|
|
if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
|
|
|
/*
|
|
|
* TSF sync does not look correct; remain awake to sync with
|
|
@@ -377,6 +378,7 @@ void ath9k_tasklet(unsigned long data)
|
|
|
ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n");
|
|
|
sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
|
|
|
}
|
|
|
+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
|
|
|
|
|
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
|
|
rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
|
|
@@ -526,8 +528,10 @@ irqreturn_t ath_isr(int irq, void *dev)
|
|
|
/* Clear RxAbort bit so that we can
|
|
|
* receive frames */
|
|
|
ath9k_setpower(sc, ATH9K_PM_AWAKE);
|
|
|
+ spin_lock(&sc->sc_pm_lock);
|
|
|
ath9k_hw_setrxabort(sc->sc_ah, 0);
|
|
|
sc->ps_flags |= PS_WAIT_FOR_BEACON;
|
|
|
+ spin_unlock(&sc->sc_pm_lock);
|
|
|
}
|
|
|
|
|
|
chip_reset:
|
|
@@ -682,6 +686,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
|
struct ath_tx_control txctl;
|
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
if (sc->ps_enabled) {
|
|
|
/*
|
|
@@ -704,6 +709,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|
|
* completed and if needed, also for RX of buffered frames.
|
|
|
*/
|
|
|
ath9k_ps_wakeup(sc);
|
|
|
+ spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
|
|
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
|
|
|
ath9k_hw_setrxabort(sc->sc_ah, 0);
|
|
|
if (ieee80211_is_pspoll(hdr->frame_control)) {
|
|
@@ -719,6 +725,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|
|
* the ps_flags bit is cleared. We are just dropping
|
|
|
* the ps_usecount here.
|
|
|
*/
|
|
|
+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
|
|
ath9k_ps_restore(sc);
|
|
|
}
|
|
|
|
|
@@ -1479,7 +1486,7 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
|
|
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
|
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
|
|
|
struct ath_vif *avp = (void *)vif->drv_priv;
|
|
|
-
|
|
|
+ unsigned long flags;
|
|
|
/*
|
|
|
* Skip iteration if primary station vif's bss info
|
|
|
* was not changed
|
|
@@ -1501,7 +1508,10 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
|
|
|
* on the receipt of the first Beacon frame (i.e.,
|
|
|
* after time sync with the AP).
|
|
|
*/
|
|
|
+ spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
|
|
sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
|
|
|
+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
|
|
+
|
|
|
/* Reset rssi stats */
|
|
|
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
|
|
|
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
|