Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 79499
b: refs/heads/master
c: 036cd1e
h: refs/heads/master
i:
  79497: 27682cd
  79495: 5508602
v: v3
  • Loading branch information
Bruno Randolf authored and David S. Miller committed Jan 28, 2008
1 parent 96df75d commit 19ebbd1
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 14 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: 9804b98d57f9b3b02a8906b0b45f461ce0c08428
refs/heads/master: 036cd1ec038f7e3a36740beaf2aa4a0d2e8ed2c1
79 changes: 66 additions & 13 deletions trunk/drivers/net/wireless/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,34 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
return 0;
}


static void
ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb)
{
u32 hw_tu;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;

if ((mgmt->frame_control & IEEE80211_FCTL_FTYPE) ==
IEEE80211_FTYPE_MGMT &&
(mgmt->frame_control & IEEE80211_FCTL_STYPE) ==
IEEE80211_STYPE_BEACON &&
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.
*/
hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah));
if (hw_tu >= sc->nexttbtt) {
ath5k_beacon_update_timers(sc,
mgmt->u.beacon.timestamp);
ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
"detected HW merge from received beacon\n");
}
}
}


static void
ath5k_tasklet_rx(unsigned long data)
{
Expand Down Expand Up @@ -1767,6 +1795,10 @@ ath5k_tasklet_rx(unsigned long data)

ath5k_debug_dump_skb(sc, skb, "RX ", 0);

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

__ieee80211_rx(sc->hw, skb, &rxs);
sc->led_rxrate = ds->ds_rxstat.rs_rate;
ath5k_led_event(sc, ATH_LED_RX);
Expand Down Expand Up @@ -2057,6 +2089,8 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
}
#undef FUDGE

sc->nexttbtt = nexttbtt;

intval |= AR5K_BEACON_ENA;
ath5k_hw_init_beacon(ah, nexttbtt, intval);

Expand Down Expand Up @@ -2084,16 +2118,19 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
}


/*
* Configure the beacon timers and interrupts based on the operating mode
/**
* ath5k_beacon_config - Configure the beacon queues and interrupts
*
* @sc: struct ath5k_softc pointer we are operating on
*
* When operating in station mode we want to receive a BMISS interrupt when we
* stop seeing beacons from the AP we've associated with so we can look for
* another AP to associate with.
*
* In IBSS mode we need to configure the beacon timers and use a self-linked tx
* descriptor if possible. If the hardware cannot deal with that we enable SWBA
* interrupts to send the beacons from the interrupt handler.
* In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
* interrupts to detect HW merges only.
*
* AP mode is missing.
*/
static void
ath5k_beacon_config(struct ath5k_softc *sc)
Expand All @@ -2107,17 +2144,17 @@ ath5k_beacon_config(struct ath5k_softc *sc)
sc->imask |= AR5K_INT_BMISS;
} else if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
/*
* In IBSS mode enable the beacon timers but only enable SWBA
* interrupts if we need to manually prepare beacon frames.
* Otherwise we use a self-linked tx descriptor and let the
* hardware deal with things. In that case we have to load it
* In IBSS mode we use a self-linked tx descriptor and let the
* 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).
*/
ath5k_beaconq_config(sc);

if (!ath5k_hw_hasveol(ah))
sc->imask |= AR5K_INT_SWBA;
else
sc->imask |= AR5K_INT_SWBA;

if (ath5k_hw_hasveol(ah))
ath5k_beacon_send(sc);
}
/* TODO else AP */
Expand Down Expand Up @@ -2320,8 +2357,24 @@ ath5k_intr(int irq, void *dev_id)
* Handle beacon transmission directly; deferring
* this is too slow to meet timing constraints
* under load.
*
* 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).
*/
ath5k_beacon_send(sc);
if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
/* XXX: only if VEOL suppported */
u64 tsf = ath5k_hw_get_tsf64(ah);
sc->nexttbtt += sc->bintval;
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
"SWBA nexttbtt: %x hw_tu: %x "
"TSF: %llx\n",
sc->nexttbtt,
TSF_TO_TU(tsf), tsf);
} else {
ath5k_beacon_send(sc);
}
}
if (status & AR5K_INT_RXEOL) {
/*
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/ath5k/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ struct ath5k_softc {
bmisscount, /* missed beacon transmits */
bintval, /* beacon interval in TU */
bsent;
unsigned int nexttbtt; /* next beacon time in TU */

struct timer_list calib_tim; /* calibration timer */
};
Expand Down

0 comments on commit 19ebbd1

Please sign in to comment.