Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 90143
b: refs/heads/master
c: 6ba81c2
h: refs/heads/master
i:
  90141: 9303507
  90139: b8905b5
  90135: eb67ace
  90127: c83cbb1
  90111: db57e95
v: v3
  • Loading branch information
Bruno Randolf authored and John W. Linville committed Mar 7, 2008
1 parent 01f0242 commit fdf52eb
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e14296cabac60806606b4ebc1a83ee4697876346
refs/heads/master: 6ba81c2c989291c5893014f84805ce9d196778b0
59 changes: 45 additions & 14 deletions trunk/drivers/net/wireless/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1715,8 +1715,10 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,


static void
ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb)
ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
struct ieee80211_rx_status *rxs)
{
u64 tsf, bc_tstamp;
u32 hw_tu;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;

Expand All @@ -1727,16 +1729,45 @@ ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb)
le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
/*
* Received an IBSS beacon with the same BSSID. Hardware might
* have updated the TSF, check if we need to update timers.
* Received an IBSS beacon with the same BSSID. Hardware *must*
* have updated the local TSF. We have to work around various
* hardware bugs, though...
*/
hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah));
if (hw_tu >= sc->nexttbtt) {
ath5k_beacon_update_timers(sc,
le64_to_cpu(mgmt->u.beacon.timestamp));
tsf = ath5k_hw_get_tsf64(sc->ah);
bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp);
hw_tu = TSF_TO_TU(tsf);

ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
"beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
bc_tstamp, rxs->mactime,
(rxs->mactime - bc_tstamp), tsf);

/*
* Sometimes the HW will give us a wrong tstamp in the rx
* status, causing the timestamp extension to go wrong.
* (This seems to happen especially with beacon frames bigger
* than 78 byte (incl. FCS))
* But we know that the receive timestamp must be later than the
* timestamp of the beacon since HW must have synced to that.
*
* NOTE: here we assume mactime to be after the frame was
* received, not like mac80211 which defines it at the start.
*/
if (bc_tstamp > rxs->mactime) {
ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
"detected HW merge from received beacon\n");
"fixing mactime from %llx to %llx\n",
rxs->mactime, tsf);
rxs->mactime = tsf;
}

/*
* Local TSF might have moved higher than our beacon timers,
* in that case we have to update them to continue sending
* beacons. This also takes care of synchronizing beacon sending
* times with other stations.
*/
if (hw_tu >= sc->nexttbtt)
ath5k_beacon_update_timers(sc, bc_tstamp);
}
}

Expand Down Expand Up @@ -1885,7 +1916,7 @@ ath5k_tasklet_rx(unsigned long data)

/* check beacons in IBSS mode */
if (sc->opmode == IEEE80211_IF_TYPE_IBSS)
ath5k_check_ibss_hw_merge(sc, skb);
ath5k_check_ibss_tsf(sc, skb, &rxs);

__ieee80211_rx(sc->hw, skb, &rxs);
sc->led_rxrate = rs.rs_rate;
Expand Down Expand Up @@ -2118,7 +2149,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
* beacon timer registers.
*
* This is called in a variety of situations, e.g. when a beacon is received,
* when a HW merge has been detected, but also when an new IBSS is created or
* when a TSF update has been detected, but also when an new IBSS is created or
* when we otherwise know we have to update the timers, but we keep it in this
* function to have it all together in one place.
*/
Expand Down Expand Up @@ -2218,7 +2249,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
* another AP to associate with.
*
* In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
* interrupts to detect HW merges only.
* interrupts to detect TSF updates only.
*
* AP mode is missing.
*/
Expand All @@ -2238,7 +2269,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
* hardware send the beacons automatically. We have to load it
* only once here.
* We use the SWBA interrupt only to keep track of the beacon
* timers in order to detect HW merges (automatic TSF updates).
* timers in order to detect automatic TSF updates.
*/
ath5k_beaconq_config(sc);

Expand Down Expand Up @@ -2451,8 +2482,8 @@ ath5k_intr(int irq, void *dev_id)
*
* In IBSS mode we use this interrupt just to
* keep track of the next TBTT (target beacon
* transmission time) in order to detect hardware
* merges (TSF updates).
* transmission time) in order to detect wether
* automatic TSF updates happened.
*/
if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
/* XXX: only if VEOL suppported */
Expand Down

0 comments on commit fdf52eb

Please sign in to comment.