2009-05-14 18:30:52

by Jouni Malinen

[permalink] [raw]
Subject: [PATCH 4/4] ath9k: Move PS wakeup/restore calls from isr to tasklet

From: Vasanthakumar Thiagarajan <[email protected]>

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 <[email protected]>
Signed-off-by: Jouni Malinen <[email protected]>

---
drivers/net/wireless/ath/ath9k/main.c | 23 +++++++++--------------
drivers/net/wireless/ath/ath9k/recv.c | 2 --
2 files changed, 9 insertions(+), 16 deletions(-)

--- wireless-testing.orig/drivers/net/wireless/ath/ath9k/main.c 2009-05-14 21:04:10.000000000 +0300
+++ wireless-testing/drivers/net/wireless/ath/ath9k/main.c 2009-05-14 21:13:14.000000000 +0300
@@ -455,8 +455,11 @@ static void ath9k_tasklet(unsigned long
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;
}

@@ -471,6 +474,7 @@ static void ath9k_tasklet(unsigned long

/* 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)
@@ -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
@@ -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;
@@ -560,20 +559,16 @@ 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) {
--- wireless-testing.orig/drivers/net/wireless/ath/ath9k/recv.c 2009-05-14 21:12:24.000000000 +0300
+++ wireless-testing/drivers/net/wireless/ath/ath9k/recv.c 2009-05-14 21:13:14.000000000 +0300
@@ -508,8 +508,6 @@ static bool ath_beacon_dtim_pending_cab(
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)

--

--
Jouni Malinen PGP id EFC895FA


2009-05-15 06:47:16

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath9k: Move PS wakeup/restore calls from isr to tasklet

On Thu, May 14, 2009 at 09:28:49PM +0300, Jouni Malinen wrote:
> From: Vasanthakumar Thiagarajan <[email protected]>
>
> 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 <[email protected]>
> Signed-off-by: Jouni Malinen <[email protected]>

John, this one is misisng one line, please apply this one instead:

From: Vasanthakumar Thiagarajan <[email protected]>
Subject: [PATCH] ath9k: Move PS wakeup/restore calls from isr to tasklet

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 <[email protected]>
Signed-off-by: Jouni Malinen <[email protected]>
---
drivers/net/wireless/ath/ath9k/main.c | 22 +++++++++-------------
drivers/net/wireless/ath/ath9k/recv.c | 2 --
2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index bbbfdcd..df9b7c1 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -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;
}

@@ -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)
@@ -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
@@ -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;
@@ -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) {
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 72e9283..5567517 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -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)
--
1.6.2.2.446.gfbdc0