Skip to content

Commit

Permalink
ath9k: Add support for multiple virtual AP interfaces
Browse files Browse the repository at this point in the history
This patch fixes the TSF offset calculation for staggered Beacon frames
and sets ATH_BCBUF back to the earlier value 4 to enable multi-BSS
configurations of up to four BSSes.

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 Mar 28, 2009
1 parent 1143237 commit 4ed96f0
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 26 deletions.
3 changes: 2 additions & 1 deletion drivers/net/wireless/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid

struct ath_vif {
int av_bslot;
__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
enum nl80211_iftype av_opmode;
struct ath_buf *av_bcbuf;
struct ath_tx_control av_btxctl;
Expand All @@ -406,7 +407,7 @@ struct ath_vif {
* number of beacon intervals, the game's up.
*/
#define BSTUCK_THRESH (9 * ATH_BCBUF)
#define ATH_BCBUF 1
#define ATH_BCBUF 4
#define ATH_DEFAULT_BINTVAL 100 /* TU */
#define ATH_DEFAULT_BMISS_LIMIT 10
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
Expand Down
50 changes: 25 additions & 25 deletions drivers/net/wireless/ath9k/beacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
bf->bf_mpdu = skb;
if (skb == NULL)
return NULL;
((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
avp->tsf_adjust;

info = IEEE80211_SKB_CB(skb);
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
Expand Down Expand Up @@ -253,7 +255,6 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
{
struct ath_softc *sc = aphy->sc;
struct ath_vif *avp;
struct ieee80211_hdr *hdr;
struct ath_buf *bf;
struct sk_buff *skb;
__le64 tstamp;
Expand Down Expand Up @@ -316,42 +317,33 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)

tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
sc->beacon.bc_tstamp = le64_to_cpu(tstamp);

/*
* Calculate a TSF adjustment factor required for
* staggered beacons. Note that we assume the format
* of the beacon frame leaves the tstamp field immediately
* following the header.
*/
/* Calculate a TSF adjustment factor required for staggered beacons. */
if (avp->av_bslot > 0) {
u64 tsfadjust;
__le64 val;
int intval;

intval = sc->hw->conf.beacon_int ?
sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;

/*
* The beacon interval is in TU's; the TSF in usecs.
* We figure out how many TU's to add to align the
* timestamp then convert to TSF units and handle
* byte swapping before writing it in the frame.
* The hardware will then add this each time a beacon
* frame is sent. Note that we align vif's 1..N
* and leave vif 0 untouched. This means vap 0
* has a timestamp in one beacon interval while the
* others get a timestamp aligned to the next interval.
* Calculate the TSF offset for this beacon slot, i.e., the
* number of usecs that need to be added to the timestamp field
* in Beacon and Probe Response frames. Beacon slot 0 is
* processed at the correct offset, so it does not require TSF
* adjustment. Other slots are adjusted to get the timestamp
* close to the TBTT for the BSS.
*/
tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF;
val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */
tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));

DPRINTF(sc, ATH_DBG_BEACON,
"stagger beacons, bslot %d intval %u tsfadjust %llu\n",
avp->av_bslot, intval, (unsigned long long)tsfadjust);

hdr = (struct ieee80211_hdr *)skb->data;
memcpy(&hdr[1], &val, sizeof(val));
}
((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
avp->tsf_adjust;
} else
avp->tsf_adjust = cpu_to_le64(0);

bf->bf_mpdu = skb;
bf->bf_buf_addr = bf->bf_dmacontext =
Expand Down Expand Up @@ -447,8 +439,16 @@ void ath_beacon_tasklet(unsigned long data)
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf);
slot = ((tsftu % intval) * ATH_BCBUF) / intval;
vif = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
aphy = sc->beacon.bslot_aphy[(slot + 1) % ATH_BCBUF];
/*
* Reverse the slot order to get slot 0 on the TBTT offset that does
* not require TSF adjustment and other slots adding
* slot/ATH_BCBUF * beacon_int to timestamp. For example, with
* ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
* and slot 0 is at correct offset to TBTT.
*/
slot = ATH_BCBUF - slot - 1;
vif = sc->beacon.bslot[slot];
aphy = sc->beacon.bslot_aphy[slot];

DPRINTF(sc, ATH_DBG_BEACON,
"slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
Expand Down

0 comments on commit 4ed96f0

Please sign in to comment.