aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vasanth@atheros.com>2009-05-15 02:47:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-20 14:46:30 -0400
commit153e080da6a07ed888a0a59c45e28bc7351407ff (patch)
tree7d772b65967747146b6b14af2a61fa3f53617edd /drivers/net/wireless/ath/ath9k
parente3da574a0ddd3e90a1e2b788b84b94bc17a75172 (diff)
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 <vasanth@atheros.com> Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
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 0e8f6d41a375..c161b75cded6 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)
455 struct ath_softc *sc = (struct ath_softc *)data; 455 struct ath_softc *sc = (struct ath_softc *)data;
456 u32 status = sc->intrstatus; 456 u32 status = sc->intrstatus;
457 457
458 ath9k_ps_wakeup(sc);
459
458 if (status & ATH9K_INT_FATAL) { 460 if (status & ATH9K_INT_FATAL) {
459 ath_reset(sc, false); 461 ath_reset(sc, false);
462 ath9k_ps_restore(sc);
460 return; 463 return;
461 } 464 }
462 465
@@ -471,6 +474,7 @@ static void ath9k_tasklet(unsigned long data)
471 474
472 /* re-enable hardware interrupt */ 475 /* re-enable hardware interrupt */
473 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 476 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
477 ath9k_ps_restore(sc);
474} 478}
475 479
476irqreturn_t ath_isr(int irq, void *dev) 480irqreturn_t ath_isr(int irq, void *dev)
@@ -498,14 +502,11 @@ irqreturn_t ath_isr(int irq, void *dev)
498 if (sc->sc_flags & SC_OP_INVALID) 502 if (sc->sc_flags & SC_OP_INVALID)
499 return IRQ_NONE; 503 return IRQ_NONE;
500 504
501 ath9k_ps_wakeup(sc);
502 505
503 /* shared irq, not for us */ 506 /* shared irq, not for us */
504 507
505 if (!ath9k_hw_intrpend(ah)) { 508 if (!ath9k_hw_intrpend(ah))
506 ath9k_ps_restore(sc);
507 return IRQ_NONE; 509 return IRQ_NONE;
508 }
509 510
510 /* 511 /*
511 * Figure out the reason(s) for the interrupt. Note 512 * Figure out the reason(s) for the interrupt. Note
@@ -520,10 +521,8 @@ irqreturn_t ath_isr(int irq, void *dev)
520 * If there are no status bits set, then this interrupt was not 521 * If there are no status bits set, then this interrupt was not
521 * for me (should have been caught above). 522 * for me (should have been caught above).
522 */ 523 */
523 if (!status) { 524 if (!status)
524 ath9k_ps_restore(sc);
525 return IRQ_NONE; 525 return IRQ_NONE;
526 }
527 526
528 /* Cache the status */ 527 /* Cache the status */
529 sc->intrstatus = status; 528 sc->intrstatus = status;
@@ -560,20 +559,17 @@ irqreturn_t ath_isr(int irq, void *dev)
560 ath9k_hw_set_interrupts(ah, sc->imask); 559 ath9k_hw_set_interrupts(ah, sc->imask);
561 } 560 }
562 561
563 if (status & ATH9K_INT_TIM_TIMER) { 562 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
564 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 563 if (status & ATH9K_INT_TIM_TIMER) {
565 /* Clear RxAbort bit so that we can 564 /* Clear RxAbort bit so that we can
566 * receive frames */ 565 * receive frames */
567 ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); 566 ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
568 ath9k_hw_setrxabort(ah, 0); 567 ath9k_hw_setrxabort(sc->sc_ah, 0);
569 sched = true;
570 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; 568 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
571 } 569 }
572 }
573 570
574chip_reset: 571chip_reset:
575 572
576 ath9k_ps_restore(sc);
577 ath_debug_stat_interrupt(sc, status); 573 ath_debug_stat_interrupt(sc, status);
578 574
579 if (sched) { 575 if (sched) {
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 72e9283bcf7b..5567517aa641 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)
508static void ath_rx_ps_back_to_sleep(struct ath_softc *sc) 508static void ath_rx_ps_back_to_sleep(struct ath_softc *sc)
509{ 509{
510 sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB); 510 sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
511 if (sc->hw->conf.flags & IEEE80211_CONF_PS)
512 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
513} 511}
514 512
515static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) 513static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)