Skip to content

Commit

Permalink
ath9k: Update Beacon timers based on timestamp from the AP
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jouni Malinen authored and John W. Linville committed May 22, 2009
1 parent 267a901 commit ccdfeab
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ struct ath_rfkill {
#define SC_OP_WAIT_FOR_CAB BIT(16)
#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
#define SC_OP_WAIT_FOR_TX_ACK BIT(18)
#define SC_OP_BEACON_SYNC BIT(19)

struct ath_bus_ops {
void (*read_cachesize)(struct ath_softc *sc, int *csz);
Expand Down
9 changes: 8 additions & 1 deletion drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ static void ath9k_tasklet(unsigned long data)
* the next Beacon.
*/
DPRINTF(sc, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n");
sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
}

/* re-enable hardware interrupt */
Expand Down Expand Up @@ -914,6 +914,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
if (avp->av_opmode == NL80211_IFTYPE_STATION) {
sc->curaid = bss_conf->aid;
ath9k_hw_write_associd(sc);

/*
* Request a re-configuration of Beacon related timers
* on the receipt of the first Beacon frame (i.e.,
* after time sync with the AP).
*/
sc->sc_flags |= SC_OP_BEACON_SYNC;
}

/* Configure the beacon */
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/wireless/ath/ath9k/recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,13 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0)
return; /* not from our current AP */

if (sc->sc_flags & SC_OP_BEACON_SYNC) {
sc->sc_flags &= ~SC_OP_BEACON_SYNC;
DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on "
"timestamp from the AP\n");
ath_beacon_config(sc, NULL);
}

if (!(sc->hw->conf.flags & IEEE80211_CONF_PS)) {
/* We are not in PS mode anymore; remain awake */
DPRINTF(sc, ATH_DBG_PS, "Not in PS mode anymore, remain "
Expand Down

0 comments on commit ccdfeab

Please sign in to comment.