2012-03-12 23:47:05

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 1/3] mac80211: Record timing offset (Toffset) for all mesh neighbors

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



2012-03-12 23:47:07

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 3/3] nl80211: Read Toffset for each station

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


2012-03-13 07:54:45

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/3] cfg80211: Fill Toffset for each station

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


2012-03-12 23:47:06

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 2/3] cfg80211: Fill Toffset for each station

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