Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 352657
b: refs/heads/master
c: ef429da
h: refs/heads/master
i:
  352655: 526e533
v: v3
  • Loading branch information
Johannes Berg committed Feb 11, 2013
1 parent 2a37c91 commit b7c6dd1
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 8 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: 8cef2c9df88fdd13f518e6607de9d664b31f26cc
refs/heads/master: ef429dadf33feeb150098dbe84ccaa877e3261f6
14 changes: 13 additions & 1 deletion trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,16 @@ enum ieee80211_rssi_event {
* valid in station mode only if after the driver was notified
* with the %BSS_CHANGED_DTIM_PERIOD flag, will be non-zero then.
* @sync_tsf: last beacon's/probe response's TSF timestamp (could be old
* as it may have been received during scanning long ago)
* as it may have been received during scanning long ago). If the
* HW flag %IEEE80211_HW_TIMING_BEACON_ONLY is set, then this can
* only come from a beacon, but might not become valid until after
* association when a beacon is received (which is notified with the
* %BSS_CHANGED_DTIM flag.)
* @sync_device_ts: the device timestamp corresponding to the sync_tsf,
* the driver/device can use this to calculate synchronisation
* (see @sync_tsf)
* @sync_dtim_count: Only valid when %IEEE80211_HW_TIMING_BEACON_ONLY
* is requested, see @sync_tsf/@sync_device_ts.
* @beacon_int: beacon interval
* @assoc_capability: capabilities taken from assoc resp
* @basic_rates: bitmap of basic rates, each bit stands for an
Expand Down Expand Up @@ -331,6 +338,7 @@ struct ieee80211_bss_conf {
u16 assoc_capability;
u64 sync_tsf;
u32 sync_device_ts;
u8 sync_dtim_count;
u32 basic_rates;
int mcast_rate[IEEE80211_NUM_BANDS];
u16 ht_operation_mode;
Expand Down Expand Up @@ -1371,6 +1379,9 @@ struct ieee80211_tx_control {
* @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any
* P2P Interface. This will be honoured even if more than one interface
* is supported.
*
* @IEEE80211_HW_TIMING_BEACON_ONLY: Use sync timing from beacon frames
* only, to allow getting TBTT of a DTIM beacon.
*/
enum ieee80211_hw_flags {
IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
Expand Down Expand Up @@ -1399,6 +1410,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23,
IEEE80211_HW_SCAN_WHILE_IDLE = 1<<24,
IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25,
IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26,
};

/**
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ struct ieee80211_fragment_entry {


struct ieee80211_bss {
u32 device_ts;
u32 device_ts_beacon, device_ts_presp;

bool wmm_used;
bool uapsd_supported;
Expand Down
65 changes: 61 additions & 4 deletions trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -2567,6 +2567,17 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
ifmgd->assoc_data->have_beacon = true;
ifmgd->assoc_data->need_beacon = false;
if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
sdata->vif.bss_conf.sync_tsf =
le64_to_cpu(mgmt->u.beacon.timestamp);
sdata->vif.bss_conf.sync_device_ts =
rx_status->device_timestamp;
if (elems.tim)
sdata->vif.bss_conf.sync_dtim_count =
elems.tim->dtim_count;
else
sdata->vif.bss_conf.sync_dtim_count = 0;
}
/* continue assoc process */
ifmgd->assoc_data->timeout = jiffies;
run_again(ifmgd, ifmgd->assoc_data->timeout);
Expand Down Expand Up @@ -2725,14 +2736,27 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,

/*
* If we haven't had a beacon before, tell the driver about the
* DTIM period now.
* DTIM period (and beacon timing if desired) now.
*/
if (!bss_conf->dtim_period) {
/* a few bogus AP send dtim_period = 0 or no TIM IE */
if (elems.tim)
bss_conf->dtim_period = elems.tim->dtim_period ?: 1;
else
bss_conf->dtim_period = 1;

if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
sdata->vif.bss_conf.sync_tsf =
le64_to_cpu(mgmt->u.beacon.timestamp);
sdata->vif.bss_conf.sync_device_ts =
rx_status->device_timestamp;
if (elems.tim)
sdata->vif.bss_conf.sync_dtim_count =
elems.tim->dtim_count;
else
sdata->vif.bss_conf.sync_dtim_count = 0;
}

changed |= BSS_CHANGED_DTIM_PERIOD;
}

Expand Down Expand Up @@ -3712,10 +3736,33 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
/* set timing information */
sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
rcu_read_lock();
ies = rcu_dereference(cbss->ies);
sdata->vif.bss_conf.sync_tsf = ies->tsf;
ies = rcu_dereference(cbss->beacon_ies);
if (ies) {
const u8 *tim_ie;

sdata->vif.bss_conf.sync_tsf = ies->tsf;
sdata->vif.bss_conf.sync_device_ts =
bss->device_ts_beacon;
tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
ies->data, ies->len);
if (tim_ie && tim_ie[1] >= 2)
sdata->vif.bss_conf.sync_dtim_count = tim_ie[2];
else
sdata->vif.bss_conf.sync_dtim_count = 0;
} else if (!(local->hw.flags &
IEEE80211_HW_TIMING_BEACON_ONLY)) {
ies = rcu_dereference(cbss->proberesp_ies);
/* must be non-NULL since beacon IEs were NULL */
sdata->vif.bss_conf.sync_tsf = ies->tsf;
sdata->vif.bss_conf.sync_device_ts =
bss->device_ts_presp;
sdata->vif.bss_conf.sync_dtim_count = 0;
} else {
sdata->vif.bss_conf.sync_tsf = 0;
sdata->vif.bss_conf.sync_device_ts = 0;
sdata->vif.bss_conf.sync_dtim_count = 0;
}
rcu_read_unlock();
sdata->vif.bss_conf.sync_device_ts = bss->device_ts;

/* tell driver about BSSID, basic rates and timing */
ieee80211_bss_info_change_notify(sdata,
Expand Down Expand Up @@ -4041,13 +4088,23 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
beacon_ies->data,
beacon_ies->len);
u8 dtim_count = 0;

if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) {
const struct ieee80211_tim_ie *tim;
tim = (void *)(tim_ie + 2);
ifmgd->dtim_period = tim->dtim_period;
dtim_count = tim->dtim_count;
}
assoc_data->have_beacon = true;
assoc_data->timeout = jiffies;

if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
sdata->vif.bss_conf.sync_tsf = beacon_ies->tsf;
sdata->vif.bss_conf.sync_device_ts =
bss->device_ts_beacon;
sdata->vif.bss_conf.sync_dtim_count = dtim_count;
}
} else {
assoc_data->timeout = jiffies;
}
Expand Down
5 changes: 4 additions & 1 deletion trunk/net/mac80211/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ ieee80211_bss_info_update(struct ieee80211_local *local,

bss = (void *)cbss->priv;

bss->device_ts = rx_status->device_timestamp;
if (beacon)
bss->device_ts_beacon = rx_status->device_timestamp;
else
bss->device_ts_presp = rx_status->device_timestamp;

if (elems->parse_error) {
if (beacon)
Expand Down
2 changes: 2 additions & 0 deletions trunk/net/mac80211/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ TRACE_EVENT(drv_bss_info_changed,
__field(u16, assoc_cap)
__field(u64, sync_tsf)
__field(u32, sync_device_ts)
__field(u8, sync_dtim_count)
__field(u32, basic_rates)
__array(int, mcast_rate, IEEE80211_NUM_BANDS)
__field(u16, ht_operation_mode)
Expand Down Expand Up @@ -379,6 +380,7 @@ TRACE_EVENT(drv_bss_info_changed,
__entry->assoc_cap = info->assoc_capability;
__entry->sync_tsf = info->sync_tsf;
__entry->sync_device_ts = info->sync_device_ts;
__entry->sync_dtim_count = info->sync_dtim_count;
__entry->basic_rates = info->basic_rates;
memcpy(__entry->mcast_rate, info->mcast_rate,
sizeof(__entry->mcast_rate));
Expand Down

0 comments on commit b7c6dd1

Please sign in to comment.