802.11s standard introduced timing offset calculation by mesh stations. The
mesh STA shall calculate the timing offset value with respect to the neighbor
STA with which it maintains synchronization.
Toffset = timestamp from beacon/probe response frames -
frame reception time (mactime).
Signed-off-by: Ashok Nagarajan <[email protected]>
Signed-off-by: Javier Cardona <[email protected]>
---
net/mac80211/mesh.c | 8 +++++++-
net/mac80211/mesh.h | 2 +-
net/mac80211/mesh_plink.c | 3 ++-
net/mac80211/sta_info.h | 2 ++
4 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index e5fbb7c..bbf5807 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -621,6 +621,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
u32 supp_rates = 0;
size_t baselen;
int freq;
+ s64 t_offset = 0;
enum ieee80211_band band = rx_status->band;
/* ignore ProbeResp to foreign address */
@@ -649,10 +650,15 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
return;
+ if (rx_status->flag & RX_FLAG_MACTIME_MPDU)
+ t_offset = le64_to_cpu(mgmt->u.beacon.timestamp) -
+ rx_status->mactime;
+
if (elems.mesh_id && elems.mesh_config &&
mesh_matches_local(&elems, sdata)) {
supp_rates = ieee80211_sta_get_rates(local, &elems, band);
- mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems);
+ mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems,
+ t_offset);
}
}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 8d53b71..d867cc8 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -258,7 +258,7 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
/* Mesh plinks */
void mesh_neighbour_update(u8 *hw_addr, u32 rates,
struct ieee80211_sub_if_data *sdata,
- struct ieee802_11_elems *ie);
+ struct ieee802_11_elems *ie, s64 t_offset);
bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
void mesh_plink_broken(struct sta_info *sta);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 4e53c4c..06e5180 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -276,7 +276,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
void mesh_neighbour_update(u8 *hw_addr, u32 rates,
struct ieee80211_sub_if_data *sdata,
- struct ieee802_11_elems *elems)
+ struct ieee802_11_elems *elems, s64 t_offset)
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
@@ -304,6 +304,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
sta->last_rx = jiffies;
sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
+ sta->t_offset = t_offset;
if (mesh_peer_accepts_plinks(elems) &&
sta->plink_state == NL80211_PLINK_LISTEN &&
sdata->u.mesh.accepting_plinks &&
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index ab05768..764eb65 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -264,6 +264,7 @@ struct sta_ampdu_mlme {
* @plink_timeout: timeout of peer link
* @plink_timer: peer link watch timer
* @plink_timer_was_running: used by suspend/resume to restore timers
+ * @t_offset: timing offset relative to this host
* @debugfs: debug filesystem info
* @dead: set to true when sta is unlinked
* @uploaded: set to true when sta is uploaded to the driver
@@ -353,6 +354,7 @@ struct sta_info {
enum nl80211_plink_state plink_state;
u32 plink_timeout;
struct timer_list plink_timer;
+ s64 t_offset;
#endif
#ifdef CONFIG_MAC80211_DEBUGFS
--
1.7.5.4
Signed-off-by: Ashok Nagarajan <[email protected]>
Signed-off-by: Javier Cardona <[email protected]>
---
include/linux/nl80211.h | 2 ++
net/wireless/nl80211.c | 3 +++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index e474f6e..94211ff 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1685,6 +1685,7 @@ enum nl80211_sta_bss_param {
* @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
* @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
* @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
+ * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
* @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
*/
@@ -1708,6 +1709,7 @@ enum nl80211_sta_info {
NL80211_STA_INFO_CONNECTED_TIME,
NL80211_STA_INFO_STA_FLAGS,
NL80211_STA_INFO_BEACON_LOSS,
+ NL80211_STA_INFO_T_OFFSET,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4c1eb94..d7b85e1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2479,6 +2479,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
NLA_PUT(msg, NL80211_STA_INFO_STA_FLAGS,
sizeof(struct nl80211_sta_flag_update),
&sinfo->sta_flags);
+ if (sinfo->filled & STATION_INFO_T_OFFSET)
+ NLA_PUT_U64(msg, NL80211_STA_INFO_T_OFFSET,
+ sinfo->t_offset);
nla_nest_end(msg, sinfoattr);
if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
--
1.7.5.4
On Mon, 2012-03-12 at 16:46 -0700, Ashok Nagarajan wrote:
> sinfo->filled |= STATION_INFO_LLID |
> STATION_INFO_PLID |
> - STATION_INFO_PLINK_STATE;
> + STATION_INFO_PLINK_STATE |
> + STATION_INFO_T_OFFSET;
>
> sinfo->llid = le16_to_cpu(sta->llid);
> sinfo->plid = le16_to_cpu(sta->plid);
> sinfo->plink_state = sta->plink_state;
> + sinfo->t_offset = sta->t_offset;
I don't think this is a good idea. sta->t_offset is invalid when
RX_FLAG_MACTIME_MPDU was never set, so I don't think you should report
it to userspace in that case.
johannes
Signed-off-by: Ashok Nagarajan <[email protected]>
Signed-off-by: Javier Cardona <[email protected]>
---
include/net/cfg80211.h | 6 +++++-
net/mac80211/cfg.c | 4 +++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 66f4603..22c42bb 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -520,6 +520,7 @@ struct station_parameters {
* @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
* @STATION_INFO_STA_FLAGS: @sta_flags filled
* @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled
+ * @STATION_INFO_T_OFFSET: @t_offset filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -541,7 +542,8 @@ enum station_info_flags {
STATION_INFO_CONNECTED_TIME = 1<<16,
STATION_INFO_ASSOC_REQ_IES = 1<<17,
STATION_INFO_STA_FLAGS = 1<<18,
- STATION_INFO_BEACON_LOSS_COUNT = 1<<19
+ STATION_INFO_BEACON_LOSS_COUNT = 1<<19,
+ STATION_INFO_T_OFFSET = 1<<20,
};
/**
@@ -640,6 +642,7 @@ struct sta_bss_parameters {
* @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
* @sta_flags: station flags mask & values
* @beacon_loss_count: Number of times beacon loss event has triggered.
+ * @t_offset: Time offset of the station relative to this host.
*/
struct station_info {
u32 filled;
@@ -668,6 +671,7 @@ struct station_info {
size_t assoc_req_ies_len;
u32 beacon_loss_count;
+ s64 t_offset;
/*
* Note: Add a new enum station_info_flags value for each new field and
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 677d659..5639157 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -407,11 +407,13 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
STATION_INFO_PLID |
- STATION_INFO_PLINK_STATE;
+ STATION_INFO_PLINK_STATE |
+ STATION_INFO_T_OFFSET;
sinfo->llid = le16_to_cpu(sta->llid);
sinfo->plid = le16_to_cpu(sta->plid);
sinfo->plink_state = sta->plink_state;
+ sinfo->t_offset = sta->t_offset;
#endif
}
--
1.7.5.4