diff options
author | Jouni Malinen <jouni.malinen@atheros.com> | 2009-05-20 14:59:08 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-22 14:06:01 -0400 |
commit | ccdfeab6536ae55d43436ffaae949afde6e962ca (patch) | |
tree | df00994be9edcaf8e8fd4d97ebafe74e710722d5 /drivers/net/wireless/ath | |
parent | 267a90127472be70b02ab13cbd355b5013e2aa51 (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')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 7 |
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 | ||
522 | struct ath_bus_ops { | 523 | struct 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 " |