aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.c
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2012-03-31 14:31:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-10 15:20:31 -0400
commitdbf498fbafa2c23139d5a990e94ed78bafbbea19 (patch)
tree723a2ed4575ab2178cbd210d85a19d5c968a95a1 /net/mac80211/mesh.c
parent9bdd3a6bf8513a0a9eda031d15b36e4677854243 (diff)
mac80211: Implement mesh synchronization framework
This patch adds MBSS extensible synchronization framework (Sec. 13.13.2 of IEEE Std. 802.11-2012). The framework is implemented via an ops table which defines the following functions: rx_bcn_presp() - this is called every time a mesh beacon is received. adjust_tbtt() - this is called immediately before a beacon is about to be transmitted. The default neighbor offset synchronization defined in the standard is implemented. We also provide template functions for vendor specific methods. When neighbor offset synchronization is active (which is the default) mesh neighbors in the same MBSS will track timing offsets to each other and compensate clock drift. In our tests we observed that this mesh synchronization implementation successfully corrected drifts between stations of ~2PPM while introducing a jitter of ~20us. It is also possible to test this framework on mac80211_hwsim simulated phys to see how it behaves under different topologies, over poor links, etc. Signed-off-by: Marco Porsch <marco.porsch@s2005.tu-chemnitz.de> Signed-off-by: Pavel Zubarev <pavel.zubarev@gmail.com> Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r--net/mac80211/mesh.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index b05fa9ef866c..386dbca1eab3 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -13,9 +13,6 @@
13#include "ieee80211_i.h" 13#include "ieee80211_i.h"
14#include "mesh.h" 14#include "mesh.h"
15 15
16#define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01
17#define MESHCONF_CAPAB_FORWARDING 0x08
18
19#define TMR_RUNNING_HK 0 16#define TMR_RUNNING_HK 0
20#define TMR_RUNNING_MP 1 17#define TMR_RUNNING_MP 1
21#define TMR_RUNNING_MPR 2 18#define TMR_RUNNING_MPR 2
@@ -251,8 +248,10 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
251 /* Mesh capability */ 248 /* Mesh capability */
252 ifmsh->accepting_plinks = mesh_plink_availables(sdata); 249 ifmsh->accepting_plinks = mesh_plink_availables(sdata);
253 *pos = MESHCONF_CAPAB_FORWARDING; 250 *pos = MESHCONF_CAPAB_FORWARDING;
254 *pos++ |= ifmsh->accepting_plinks ? 251 *pos |= ifmsh->accepting_plinks ?
255 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 252 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
253 *pos++ |= ifmsh->adjusting_tbtt ?
254 MESHCONF_CAPAB_TBTT_ADJUSTING : 0x00;
256 *pos++ = 0x00; 255 *pos++ = 0x00;
257 256
258 return 0; 257 return 0;
@@ -573,8 +572,11 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
573 ieee80211_configure_filter(local); 572 ieee80211_configure_filter(local);
574 573
575 ifmsh->mesh_cc_id = 0; /* Disabled */ 574 ifmsh->mesh_cc_id = 0; /* Disabled */
576 ifmsh->mesh_sp_id = 0; /* Neighbor Offset */
577 ifmsh->mesh_auth_id = 0; /* Disabled */ 575 ifmsh->mesh_auth_id = 0; /* Disabled */
576 /* register sync ops from extensible synchronization framework */
577 ifmsh->sync_ops = ieee80211_mesh_sync_ops_get(ifmsh->mesh_sp_id);
578 ifmsh->adjusting_tbtt = false;
579 ifmsh->sync_offset_clockdrift_max = 0;
578 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); 580 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
579 ieee80211_mesh_root_setup(ifmsh); 581 ieee80211_mesh_root_setup(ifmsh);
580 ieee80211_queue_work(&local->hw, &sdata->work); 582 ieee80211_queue_work(&local->hw, &sdata->work);
@@ -616,6 +618,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
616 struct ieee80211_rx_status *rx_status) 618 struct ieee80211_rx_status *rx_status)
617{ 619{
618 struct ieee80211_local *local = sdata->local; 620 struct ieee80211_local *local = sdata->local;
621 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
619 struct ieee802_11_elems elems; 622 struct ieee802_11_elems elems;
620 struct ieee80211_channel *channel; 623 struct ieee80211_channel *channel;
621 u32 supp_rates = 0; 624 u32 supp_rates = 0;
@@ -654,6 +657,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
654 supp_rates = ieee80211_sta_get_rates(local, &elems, band); 657 supp_rates = ieee80211_sta_get_rates(local, &elems, band);
655 mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems); 658 mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems);
656 } 659 }
660
661 if (ifmsh->sync_ops)
662 ifmsh->sync_ops->rx_bcn_presp(sdata,
663 stype, mgmt, &elems, rx_status);
657} 664}
658 665
659static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, 666static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
@@ -721,6 +728,9 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
721 728
722 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags)) 729 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
723 ieee80211_mesh_rootpath(sdata); 730 ieee80211_mesh_rootpath(sdata);
731
732 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags))
733 mesh_sync_adjust_tbtt(sdata);
724} 734}
725 735
726void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) 736void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
@@ -761,4 +771,5 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
761 (unsigned long) sdata); 771 (unsigned long) sdata);
762 INIT_LIST_HEAD(&ifmsh->preq_queue.list); 772 INIT_LIST_HEAD(&ifmsh->preq_queue.list);
763 spin_lock_init(&ifmsh->mesh_preq_queue_lock); 773 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
774 spin_lock_init(&ifmsh->sync_offset_lock);
764} 775}