Marco, On Fri, Oct 19, 2012 at 9:32 AM, Marco Porsch <[email protected]> wrote: > > Correct, Ashok told me about that. But you are right, now after revising my > patch is really to close to that functionality. > What would you recommend to do then? > > What I had in mind with this patch is: > For PS I need to maintain a wakeup list (TBTTs of peers that we are in light > sleep towards). To keep in sync with these peers we have to make sure to > catch their beacons regularly. So what my PS code does when it notices > repeatedly missing beacons, is to completely block the radio from sleeping > until that peer's beacon is caught again. To get out of this state again, I > rely on the peer link cleanup from mac80211. > The chance of being awake, while a peer just asynchronously throws out the > close frame are low. So currently I have a forced awake time of 30min when a > peer just disappears.
How about making the IEEE80211_MESH_PEER_INACTIVITY_LIMIT a runtime configurable parameter? When entering PS mode, you could then reduce that limit to a more adequate value, say 30 seconds. Would that work for you? Javier > On 10/19/2012 09:11 AM, Javier Cardona wrote: >> >> Marco, >> >> I think that functionality is already implemented in >> ieee80211_mesh_housekeeping. We use the sinfo->inactive_time value, >> which tracks how long it has been since traffic was received from a >> peer, and that includes beacons. The >> IEEE80211_MESH_PEER_INACTIVITY_LIMIT is currently set at compile time >> to 30 min. >> >> Javier >> >> >> >> On Thu, Oct 18, 2012 at 6:54 PM, <[email protected]> wrote: >>> >>> From: Marco Porsch <[email protected]> >>> >>> Currently the mesh code relies on on a graceful peer link close with a >>> Mesh Peering Close frame. That causes peer links to stay in established >>> state after a node just silently disappeared. >>> >>> This commit adds a periodic check of the last RX time of an established >>> peer link. If the time since the last RX time is longer than a threshold >>> (given in beacon interval units), the link is closed, just as it would be >>> in case of a received Mesh Peering Close frame. >>> To calculate the timeout the peer's beacon interval is recorded and used. >>> >>> To keep a clear separation of kernel and userspace peering routines, >>> only the kernel peering routines (mesh_plink_timer, mesh_rx_plink_frame) >>> employ that timer. Userspace AMPE has to implement its own timeout >>> routine. >>> >>> Signed-off-by: Marco Porsch <[email protected]> >>> --- >>> net/mac80211/mesh.c | 2 +- >>> net/mac80211/mesh.h | 5 ++++- >>> net/mac80211/mesh_plink.c | 32 ++++++++++++++++++++++++++++---- >>> net/mac80211/sta_info.h | 2 ++ >>> 4 files changed, 35 insertions(+), 6 deletions(-) >>> >>> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c >>> index ff0296c..6d41e5d 100644 >>> --- a/net/mac80211/mesh.c >>> +++ b/net/mac80211/mesh.c >>> @@ -696,7 +696,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct >>> ieee80211_sub_if_data *sdata, >>> >>> if (elems.mesh_id && elems.mesh_config && >>> mesh_matches_local(sdata, &elems)) >>> - mesh_neighbour_update(sdata, mgmt->sa, &elems); >>> + mesh_neighbour_update(sdata, mgmt, &elems); >>> >>> if (ifmsh->sync_ops) >>> ifmsh->sync_ops->rx_bcn_presp(sdata, >>> diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h >>> index 25d0f17..7884f2b 100644 >>> --- a/net/mac80211/mesh.h >>> +++ b/net/mac80211/mesh.h >>> @@ -209,6 +209,9 @@ struct mesh_rmc { >>> >>> #define MESH_PATH_EXPIRE (600 * HZ) >>> >>> +/* timeout for established peer links (in peer's beacon interval units) >>> */ >>> +#define MESH_PLINK_ESTAB_TIMEOUT 14 >>> + >>> /* Default maximum number of plinks per interface */ >>> #define MESH_MAX_PLINKS 256 >>> >>> @@ -282,7 +285,7 @@ int mesh_path_send_to_gates(struct mesh_path *mpath); >>> int mesh_gate_num(struct ieee80211_sub_if_data *sdata); >>> /* Mesh plinks */ >>> void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, >>> - u8 *hw_addr, >>> + struct ieee80211_mgmt *mgmt, >>> struct ieee802_11_elems *ie); >>> bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); >>> u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); >>> diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c >>> index 3ab34d8..e8f528f 100644 >>> --- a/net/mac80211/mesh_plink.c >>> +++ b/net/mac80211/mesh_plink.c >>> @@ -404,13 +404,13 @@ static struct sta_info *mesh_peer_init(struct >>> ieee80211_sub_if_data *sdata, >>> } >>> >>> void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, >>> - u8 *hw_addr, >>> + struct ieee80211_mgmt *mgmt, >>> struct ieee802_11_elems *elems) >>> { >>> struct sta_info *sta; >>> >>> rcu_read_lock(); >>> - sta = mesh_peer_init(sdata, hw_addr, elems); >>> + sta = mesh_peer_init(sdata, mgmt->sa, elems); >>> if (!sta) >>> goto out; >>> >>> @@ -421,6 +421,7 @@ void mesh_neighbour_update(struct >>> ieee80211_sub_if_data *sdata, >>> rssi_threshold_check(sta, sdata)) >>> mesh_plink_open(sta); >>> >>> + sta->beacon_interval = le16_to_cpu(mgmt->u.beacon.beacon_int); >>> out: >>> rcu_read_unlock(); >>> } >>> @@ -495,6 +496,27 @@ static void mesh_plink_timer(unsigned long data) >>> mesh_plink_fsm_restart(sta); >>> spin_unlock_bh(&sta->lock); >>> break; >>> + case NL80211_PLINK_ESTAB: >>> + /* link loss timer */ >>> + if (time_after(jiffies, >>> + sta->last_rx + MESH_PLINK_ESTAB_TIMEOUT * >>> + TU_TO_JIFFIES(sta->beacon_interval))) { >>> + u32 changed = 0; >>> + >>> + mpl_dbg(sta->sdata, "Mesh peer link with %pM >>> lost\n", >>> + sta->sta.addr); >>> + changed |= __mesh_plink_deactivate(sta); >>> + sta->plink_state = NL80211_PLINK_HOLDING; >>> + mod_plink_timer(sta, >>> dot11MeshHoldingTimeout(sdata)); >>> + spin_unlock_bh(&sta->lock); >>> + changed |= mesh_set_ht_prot_mode(sdata); >>> + ieee80211_bss_info_change_notify(sdata, changed); >>> + } else { >>> + mod_plink_timer(sta, >>> + >>> TU_TO_JIFFIES(sta->beacon_interval)); >>> + spin_unlock_bh(&sta->lock); >>> + } >>> + break; >>> default: >>> spin_unlock_bh(&sta->lock); >>> break; >>> @@ -863,7 +885,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data >>> *sdata, struct ieee80211_m >>> sta->sta.addr, llid, plid, >>> 0); >>> break; >>> case CNF_ACPT: >>> - del_timer(&sta->plink_timer); >>> + mod_plink_timer(sta, >>> + >>> TU_TO_JIFFIES(sta->beacon_interval)); >>> sta->plink_state = NL80211_PLINK_ESTAB; >>> spin_unlock_bh(&sta->lock); >>> changed |= mesh_plink_inc_estab_count(sdata); >>> @@ -898,7 +921,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data >>> *sdata, struct ieee80211_m >>> sta->sta.addr, llid, plid, >>> reason); >>> break; >>> case OPN_ACPT: >>> - del_timer(&sta->plink_timer); >>> + mod_plink_timer(sta, >>> + >>> TU_TO_JIFFIES(sta->beacon_interval)); >>> sta->plink_state = NL80211_PLINK_ESTAB; >>> spin_unlock_bh(&sta->lock); >>> changed |= mesh_plink_inc_estab_count(sdata); >>> diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h >>> index c88f161f..45eae7e 100644 >>> --- a/net/mac80211/sta_info.h >>> +++ b/net/mac80211/sta_info.h >>> @@ -274,6 +274,7 @@ struct sta_ampdu_mlme { >>> * @t_offset_setpoint: reference timing offset of this sta to be used >>> when >>> * calculating clockdrift >>> * @ch_type: peer's channel type >>> + * @beacon_interval: beacon interval of this station >>> * @debugfs: debug filesystem info >>> * @dead: set to true when sta is unlinked >>> * @uploaded: set to true when sta is uploaded to the driver >>> @@ -370,6 +371,7 @@ struct sta_info { >>> s64 t_offset; >>> s64 t_offset_setpoint; >>> enum nl80211_channel_type ch_type; >>> + u16 beacon_interval; >>> #endif >>> >>> #ifdef CONFIG_MAC80211_DEBUGFS >>> -- >>> 1.7.9.5 >>> >> >> >> > -- Javier Cardona cozybit Inc. http://www.cozybit.com _______________________________________________ Devel mailing list [email protected] http://lists.open80211s.org/cgi-bin/mailman/listinfo/devel
