diff options
author | Thomas Pedersen <twpedersen@gmail.com> | 2013-12-19 10:25:15 -0800 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-01-06 20:10:47 +0100 |
commit | 057d5f4ba1e421185a8e7e0b7fadf253d41a3e83 (patch) | |
tree | 32417b8a78ea735667c46213446079e7729fde48 /net/mac80211/util.c | |
parent | 60a4fe0ae97b515f174f9bcb157cbaeff0dab8ac (diff) | |
download | blackbird-op-linux-057d5f4ba1e421185a8e7e0b7fadf253d41a3e83.tar.gz blackbird-op-linux-057d5f4ba1e421185a8e7e0b7fadf253d41a3e83.zip |
mac80211: sync dtim_count to TSF
On starting a mesh or AP BSS, the interface dtim_count
countdown should match that of the driver TSF.
Signed-off-by: Thomas Pedersen <twpedersen@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index df00f1978a77..676dc0967f37 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2734,3 +2734,44 @@ int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr, return ret; } EXPORT_SYMBOL(ieee80211_parse_p2p_noa); + +void ieee80211_recalc_dtim(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) +{ + u64 tsf = drv_get_tsf(local, sdata); + u64 dtim_count = 0; + u16 beacon_int = sdata->vif.bss_conf.beacon_int * 1024; + u8 dtim_period = sdata->vif.bss_conf.dtim_period; + struct ps_data *ps; + u8 bcns_from_dtim; + + if (tsf == -1ULL || !beacon_int || !dtim_period) + return; + + if (sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + if (!sdata->bss) + return; + + ps = &sdata->bss->ps; + } else if (ieee80211_vif_is_mesh(&sdata->vif)) { + ps = &sdata->u.mesh.ps; + } else { + return; + } + + /* + * actually finds last dtim_count, mac80211 will update in + * __beacon_add_tim(). + * dtim_count = dtim_period - (tsf / bcn_int) % dtim_period + */ + do_div(tsf, beacon_int); + bcns_from_dtim = do_div(tsf, dtim_period); + /* just had a DTIM */ + if (!bcns_from_dtim) + dtim_count = 0; + else + dtim_count = dtim_period - bcns_from_dtim; + + ps->dtim_count = dtim_count; +} |