Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 352633
b: refs/heads/master
c: 1a6404a
h: refs/heads/master
i:
  352631: 9b27e25
v: v3
  • Loading branch information
Sujith Manoharan authored and John W. Linville committed Feb 11, 2013
1 parent 955ce59 commit 6038e8a
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 28 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: dd5ee59bb005df38ca3ee00bc6ac349dc3370e4f
refs/heads/master: 1a6404a1d8497692f31808319d662c739033c491
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ struct ath_beacon_config {
u16 bmiss_timeout;
u8 dtim_count;
bool enable_beacon;
bool ibss_creator;
};

struct ath_beacon {
Expand Down
113 changes: 87 additions & 26 deletions trunk/drivers/net/wireless/ath/ath9k/beacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,12 +407,17 @@ void ath9k_beacon_tasklet(unsigned long data)
}
}

static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, u32 intval)
/*
* Both nexttbtt and intval have to be in usecs.
*/
static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt,
u32 intval, bool reset_tsf)
{
struct ath_hw *ah = sc->sc_ah;

ath9k_hw_disable_interrupts(ah);
ath9k_hw_reset_tsf(ah);
if (reset_tsf)
ath9k_hw_reset_tsf(ah);
ath9k_beaconq_config(sc);
ath9k_hw_beaconinit(ah, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
Expand Down Expand Up @@ -442,10 +447,12 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc,
else
ah->imask &= ~ATH9K_INT_SWBA;

ath_dbg(common, BEACON, "AP nexttbtt: %u intval: %u conf_intval: %u\n",
ath_dbg(common, BEACON,
"AP (%s) nexttbtt: %u intval: %u conf_intval: %u\n",
(conf->enable_beacon) ? "Enable" : "Disable",
nexttbtt, intval, conf->beacon_interval);

ath9k_beacon_init(sc, nexttbtt, intval);
ath9k_beacon_init(sc, nexttbtt, intval, true);
}

/*
Expand Down Expand Up @@ -586,17 +593,45 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
ath9k_reset_beacon_status(sc);

intval = TU_TO_USEC(conf->beacon_interval);
nexttbtt = intval;

if (conf->ibss_creator) {
nexttbtt = intval;
} else {
u32 tbtt, offset, tsftu;
u64 tsf;

/*
* Pull nexttbtt forward to reflect the current
* sync'd TSF.
*/
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
offset = tsftu % conf->beacon_interval;
tbtt = tsftu - offset;
if (offset)
tbtt += conf->beacon_interval;

nexttbtt = TU_TO_USEC(tbtt);
}

if (conf->enable_beacon)
ah->imask |= ATH9K_INT_SWBA;
else
ah->imask &= ~ATH9K_INT_SWBA;

ath_dbg(common, BEACON, "IBSS nexttbtt: %u intval: %u conf_intval: %u\n",
ath_dbg(common, BEACON,
"IBSS (%s) nexttbtt: %u intval: %u conf_intval: %u\n",
(conf->enable_beacon) ? "Enable" : "Disable",
nexttbtt, intval, conf->beacon_interval);

ath9k_beacon_init(sc, nexttbtt, intval);
ath9k_beacon_init(sc, nexttbtt, intval, conf->ibss_creator);

/*
* Set the global 'beacon has been configured' flag for the
* joiner case in IBSS mode.
*/
if (!conf->ibss_creator && conf->enable_beacon)
set_bit(SC_OP_BEACONS, &sc->sc_flags);
}

bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
Expand Down Expand Up @@ -639,6 +674,7 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc,
cur_conf->dtim_period = bss_conf->dtim_period;
cur_conf->listen_interval = 1;
cur_conf->dtim_count = 1;
cur_conf->ibss_creator = bss_conf->ibss_creator;
cur_conf->bmiss_timeout =
ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;

Expand Down Expand Up @@ -666,34 +702,59 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
{
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
unsigned long flags;
bool skip_beacon = false;

if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
ath9k_cache_beacon_config(sc, bss_conf);
ath9k_set_beacon(sc);
set_bit(SC_OP_BEACONS, &sc->sc_flags);
} else {
/*
* Take care of multiple interfaces when
* enabling/disabling SWBA.
*/
if (changed & BSS_CHANGED_BEACON_ENABLED) {
if (!bss_conf->enable_beacon &&
(sc->nbcnvifs <= 1)) {
cur_conf->enable_beacon = false;
} else if (bss_conf->enable_beacon) {
cur_conf->enable_beacon = true;
ath9k_cache_beacon_config(sc, bss_conf);
}
return;

}

/*
* Take care of multiple interfaces when
* enabling/disabling SWBA.
*/
if (changed & BSS_CHANGED_BEACON_ENABLED) {
if (!bss_conf->enable_beacon &&
(sc->nbcnvifs <= 1)) {
cur_conf->enable_beacon = false;
} else if (bss_conf->enable_beacon) {
cur_conf->enable_beacon = true;
ath9k_cache_beacon_config(sc, bss_conf);
}
}

if (cur_conf->beacon_interval) {
/*
* Configure the HW beacon registers only when we have a valid
* beacon interval.
*/
if (cur_conf->beacon_interval) {
/*
* If we are joining an existing IBSS network, start beaconing
* only after a TSF-sync has taken place. Ensure that this
* happens by setting the appropriate flags.
*/
if ((changed & BSS_CHANGED_IBSS) && !bss_conf->ibss_creator &&
bss_conf->enable_beacon) {
spin_lock_irqsave(&sc->sc_pm_lock, flags);
sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
skip_beacon = true;
} else {
ath9k_set_beacon(sc);

if (cur_conf->enable_beacon)
set_bit(SC_OP_BEACONS, &sc->sc_flags);
else
clear_bit(SC_OP_BEACONS, &sc->sc_flags);
}

/*
* Do not set the SC_OP_BEACONS flag for IBSS joiner mode
* here, it is done in ath9k_beacon_config_adhoc().
*/
if (cur_conf->enable_beacon && !skip_beacon)
set_bit(SC_OP_BEACONS, &sc->sc_flags);
else
clear_bit(SC_OP_BEACONS, &sc->sc_flags);
}
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/ath/ath9k/recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
if (sc->ps_flags & PS_BEACON_SYNC) {
sc->ps_flags &= ~PS_BEACON_SYNC;
ath_dbg(common, PS,
"Reconfigure Beacon timers based on timestamp from the AP\n");
"Reconfigure beacon timers based on synchronized timestamp\n");
ath9k_set_beacon(sc);
}

Expand Down

0 comments on commit 6038e8a

Please sign in to comment.