aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-05-20 14:59:08 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-22 14:06:01 -0400
commitccdfeab6536ae55d43436ffaae949afde6e962ca (patch)
treedf00994be9edcaf8e8fd4d97ebafe74e710722d5 /drivers/net/wireless/ath/ath9k
parent267a90127472be70b02ab13cbd355b5013e2aa51 (diff)
ath9k: Update Beacon timers based on timestamp from the AP
Some APs seem to drift away from the expected TBTT (timestamp % beacon_int_in_usec differs quite a bit from zero) which can result in us waking up way too early to receive a Beacon frame. In order to work around this, re-configure the Beacon timers after having received a Beacon frame from the AP (i.e., when we know the offset between the expected TBTT and the actual time the AP is sending out the Beacon frame). 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/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c7
3 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0d4ac43f6d91..796a3adffea0 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -518,6 +518,7 @@ struct ath_rfkill {
518#define SC_OP_WAIT_FOR_CAB BIT(16) 518#define SC_OP_WAIT_FOR_CAB BIT(16)
519#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17) 519#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
520#define SC_OP_WAIT_FOR_TX_ACK BIT(18) 520#define SC_OP_WAIT_FOR_TX_ACK BIT(18)
521#define SC_OP_BEACON_SYNC BIT(19)
521 522
522struct ath_bus_ops { 523struct ath_bus_ops {
523 void (*read_cachesize)(struct ath_softc *sc, int *csz); 524 void (*read_cachesize)(struct ath_softc *sc, int *csz);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 5759c9465029..61da08a1648c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -487,7 +487,7 @@ static void ath9k_tasklet(unsigned long data)
487 * the next Beacon. 487 * the next Beacon.
488 */ 488 */
489 DPRINTF(sc, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n"); 489 DPRINTF(sc, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n");
490 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; 490 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
491 } 491 }
492 492
493 /* re-enable hardware interrupt */ 493 /* re-enable hardware interrupt */
@@ -914,6 +914,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
914 if (avp->av_opmode == NL80211_IFTYPE_STATION) { 914 if (avp->av_opmode == NL80211_IFTYPE_STATION) {
915 sc->curaid = bss_conf->aid; 915 sc->curaid = bss_conf->aid;
916 ath9k_hw_write_associd(sc); 916 ath9k_hw_write_associd(sc);
917
918 /*
919 * Request a re-configuration of Beacon related timers
920 * on the receipt of the first Beacon frame (i.e.,
921 * after time sync with the AP).
922 */
923 sc->sc_flags |= SC_OP_BEACON_SYNC;
917 } 924 }
918 925
919 /* Configure the beacon */ 926 /* Configure the beacon */
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 5e046b58ad93..5014a19b0f75 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -521,6 +521,13 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
521 if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0) 521 if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0)
522 return; /* not from our current AP */ 522 return; /* not from our current AP */
523 523
524 if (sc->sc_flags & SC_OP_BEACON_SYNC) {
525 sc->sc_flags &= ~SC_OP_BEACON_SYNC;
526 DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on "
527 "timestamp from the AP\n");
528 ath_beacon_config(sc, NULL);
529 }
530
524 if (!(sc->hw->conf.flags & IEEE80211_CONF_PS)) { 531 if (!(sc->hw->conf.flags & IEEE80211_CONF_PS)) {
525 /* We are not in PS mode anymore; remain awake */ 532 /* We are not in PS mode anymore; remain awake */
526 DPRINTF(sc, ATH_DBG_PS, "Not in PS mode anymore, remain " 533 DPRINTF(sc, ATH_DBG_PS, "Not in PS mode anymore, remain "