Skip to content

Commit

Permalink
ath9k: Move PS wakeup/restore calls from isr to tasklet
Browse files Browse the repository at this point in the history
We do not need to do this in ath_isr() and it looks like the modified
version ends up being more stable as far as being able receive beacon
frames is concerned. Furthermore, this reduces need to move between
AWAKE and NETWORK SLEEP states when processing some unrelated
interrupts.

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Vasanthakumar Thiagarajan authored and John W. Linville committed May 20, 2009
1 parent e3da574 commit 153e080
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 15 deletions.
22 changes: 9 additions & 13 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,11 @@ static void ath9k_tasklet(unsigned long data)
struct ath_softc *sc = (struct ath_softc *)data;
u32 status = sc->intrstatus;

ath9k_ps_wakeup(sc);

if (status & ATH9K_INT_FATAL) {
ath_reset(sc, false);
ath9k_ps_restore(sc);
return;
}

Expand All @@ -471,6 +474,7 @@ static void ath9k_tasklet(unsigned long data)

/* re-enable hardware interrupt */
ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
ath9k_ps_restore(sc);
}

irqreturn_t ath_isr(int irq, void *dev)
Expand Down Expand Up @@ -498,14 +502,11 @@ irqreturn_t ath_isr(int irq, void *dev)
if (sc->sc_flags & SC_OP_INVALID)
return IRQ_NONE;

ath9k_ps_wakeup(sc);

/* shared irq, not for us */

if (!ath9k_hw_intrpend(ah)) {
ath9k_ps_restore(sc);
if (!ath9k_hw_intrpend(ah))
return IRQ_NONE;
}

/*
* Figure out the reason(s) for the interrupt. Note
Expand All @@ -520,10 +521,8 @@ irqreturn_t ath_isr(int irq, void *dev)
* If there are no status bits set, then this interrupt was not
* for me (should have been caught above).
*/
if (!status) {
ath9k_ps_restore(sc);
if (!status)
return IRQ_NONE;
}

/* Cache the status */
sc->intrstatus = status;
Expand Down Expand Up @@ -560,20 +559,17 @@ irqreturn_t ath_isr(int irq, void *dev)
ath9k_hw_set_interrupts(ah, sc->imask);
}

if (status & ATH9K_INT_TIM_TIMER) {
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
if (status & ATH9K_INT_TIM_TIMER) {
/* Clear RxAbort bit so that we can
* receive frames */
ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
ath9k_hw_setrxabort(ah, 0);
sched = true;
ath9k_hw_setrxabort(sc->sc_ah, 0);
sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
}
}

chip_reset:

ath9k_ps_restore(sc);
ath_debug_stat_interrupt(sc, status);

if (sched) {
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/ath/ath9k/recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,6 @@ static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
static void ath_rx_ps_back_to_sleep(struct ath_softc *sc)
{
sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
if (sc->hw->conf.flags & IEEE80211_CONF_PS)
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
}

static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
Expand Down

0 comments on commit 153e080

Please sign in to comment.