I am not perfectly sure if the TBTT Adjusting subfield is used correctly now. 
It would be good to clarify what it is really used for.

a) the TBTT Adjusting subfield shows that _the next beacon_ will be delayed due 
to clock drift adjustment
b) the TBTT Adjusting subfield shows that _this beacon_ is delayed due to clock 
drift adjustment

a) makes more sense in my perspective:
- to a sleeping peer STA it hints that it should expect the next beacon to be 
delayed (to adjust wakeup timers/timeouts)
- 13.13.2.2.3 says a peer STA "shall invalidate the T_offset value for this 
neighbor STA and shall not perform [T_offset and T_ClockDrift calculation]". On 
next beacon receipt with new timing and without the TBTT Adjusting subfield it 
will start recording valid T_offset values again. In case b) it would waste one 
valid T_offset value.

What do you think?

--Marco


Am 10.12.2013 22:30, schrieb Thomas Pedersen:
> This regression was introduced in "mac80211: cache mesh
> beacon".
> 
> mesh_sync_offset_adjust_tbtt()  was an assuming that the
> beacon would be rebuilt in every single pre-tbtt
> interrupt, but now the beacon update happens on the
> workqueue, and it must be ready for immediate delivery to
> the driver.
> 
> Save a pointer to the meshconf IE in the beacon_data (this
> works because both the IE pointer and beacon buffer are
> protected by the same rcu_{dereference,assign_pointer}())
> for quick updates during pre-tbtt. This is faster and a
> little prettier than iterating over the elements to find
> the meshconf IE every time.
> 
> Signed-off-by: Thomas Pedersen <[email protected]>
> ---
>  net/mac80211/ieee80211_i.h | 8 +++++++-
>  net/mac80211/mesh.c        | 5 +++++
>  net/mac80211/mesh_sync.c   | 9 ++++++++-
>  net/mac80211/tx.c          | 3 +--
>  4 files changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
> index 32bae21..5c05eaa 100644
> --- a/net/mac80211/ieee80211_i.h
> +++ b/net/mac80211/ieee80211_i.h
> @@ -232,6 +232,7 @@ struct ieee80211_rx_data {
>  struct beacon_data {
>       u8 *head, *tail;
>       int head_len, tail_len;
> +     struct ieee80211_meshconf_ie *meshconf;
>       struct rcu_head rcu_head;
>  };
>  
> @@ -540,7 +541,10 @@ struct ieee80211_mesh_sync_ops {
>                            struct ieee80211_mgmt *mgmt,
>                            struct ieee802_11_elems *elems,
>                            struct ieee80211_rx_status *rx_status);
> -     void (*adjust_tbtt)(struct ieee80211_sub_if_data *sdata);
> +
> +     /* should be called with beacon_data under RCU read lock */
> +     void (*adjust_tbtt)(struct ieee80211_sub_if_data *sdata,
> +                         struct beacon_data *beacon);
>       /* add other framework functions here */
>  };
>  
> @@ -614,6 +618,8 @@ struct ieee80211_if_mesh {
>       bool chsw_init;
>       u8 chsw_ttl;
>       u16 pre_value;
> +
> +     int meshconf_offset;
>  };
>  
>  #ifdef CONFIG_MAC80211_MESH
> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
> index 1174157..86c2d41 100644
> --- a/net/mac80211/mesh.c
> +++ b/net/mac80211/mesh.c
> @@ -259,6 +259,9 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data 
> *sdata,
>       *pos++ = WLAN_EID_MESH_CONFIG;
>       *pos++ = meshconf_len;
>  
> +     /* save a pointer for quick updates in pre-tbtt */
> +     ifmsh->meshconf_offset = pos - skb->data;
> +
>       /* Active path selection protocol ID */
>       *pos++ = ifmsh->mesh_pp_id;
>       /* Active path selection metric ID   */
> @@ -723,6 +726,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh 
> *ifmsh)
>  
>       bcn->tail_len = skb->len;
>       memcpy(bcn->tail, skb->data, bcn->tail_len);
> +     bcn->meshconf = (struct ieee80211_meshconf_ie *)
> +                                     (bcn->tail + ifmsh->meshconf_offset);
>  
>       dev_kfree_skb(skb);
>       rcu_assign_pointer(ifmsh->beacon, bcn);
> diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
> index d1cf2d5..2bc5dc2 100644
> --- a/net/mac80211/mesh_sync.c
> +++ b/net/mac80211/mesh_sync.c
> @@ -164,12 +164,15 @@ no_sync:
>       rcu_read_unlock();
>  }
>  
> -static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
> +static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata,
> +                                      struct beacon_data *beacon)
>  {
>       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
> +     u8 cap;
>  
>       WARN_ON(ifmsh->mesh_sp_id != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET);
>       BUG_ON(!rcu_read_lock_held());
> +     cap = beacon->meshconf->meshconf_cap;
>  
>       spin_lock_bh(&ifmsh->sync_offset_lock);
>  
> @@ -194,6 +197,10 @@ static void mesh_sync_offset_adjust_tbtt(struct 
> ieee80211_sub_if_data *sdata)
>               ifmsh->adjusting_tbtt = false;
>       }
>       spin_unlock_bh(&ifmsh->sync_offset_lock);
> +
> +     beacon->meshconf->meshconf_cap = ifmsh->adjusting_tbtt ?
> +                     IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING | cap :
> +                     ~IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING & cap;
>  }
>  
>  static const struct sync_method sync_methods[] = {
> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> index 6d59e21..d758509 100644
> --- a/net/mac80211/tx.c
> +++ b/net/mac80211/tx.c
> @@ -2602,8 +2602,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct 
> ieee80211_hw *hw,
>                       ieee80211_update_csa(sdata, bcn);
>  
>               if (ifmsh->sync_ops)
> -                     ifmsh->sync_ops->adjust_tbtt(
> -                                             sdata);
> +                     ifmsh->sync_ops->adjust_tbtt(sdata, bcn);
>  
>               skb = dev_alloc_skb(local->tx_headroom +
>                                   bcn->head_len +
> 
_______________________________________________
Devel mailing list
[email protected]
http://lists.open80211s.org/cgi-bin/mailman/listinfo/devel

Reply via email to