diff options
author | Rui Paulo <rpaulo@gmail.com> | 2009-11-09 18:46:56 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-13 17:43:56 -0500 |
commit | e304bfd30f356f7b75d30cad0029ecca705fd590 (patch) | |
tree | 64b466a5d6b70dba13605d5ec1ae656801caa212 /net/mac80211/mesh.c | |
parent | d19b3bf6384e66ac6e11a61ee31ed2cfe149f4d8 (diff) |
mac80211: implement a timer to send RANN action frames
RANN (Root Annoucement) frame TX. Send an action frame every second
trying to build a path to all nodes on the mesh.
Signed-off-by: Rui Paulo <rpaulo@gmail.com>
Signed-off-by: Javier Cardona <javier@cozybit.com>
Reviewed-by: Andrey Yurovsky <andrey@cozybit.com>
Tested-by: Brian Cavagnolo <brian@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r-- | net/mac80211/mesh.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 0f3e1147ec4f..88dcfe3030b1 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) | 15 | #define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) |
16 | #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) | 16 | #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) |
17 | #define IEEE80211_MESH_RANN_INTERVAL (1 * HZ) | ||
17 | 18 | ||
18 | #define MESHCONF_PP_OFFSET 0 /* Path Selection Protocol */ | 19 | #define MESHCONF_PP_OFFSET 0 /* Path Selection Protocol */ |
19 | #define MESHCONF_PM_OFFSET 1 /* Path Selection Metric */ | 20 | #define MESHCONF_PM_OFFSET 1 /* Path Selection Metric */ |
@@ -26,6 +27,7 @@ | |||
26 | 27 | ||
27 | #define TMR_RUNNING_HK 0 | 28 | #define TMR_RUNNING_HK 0 |
28 | #define TMR_RUNNING_MP 1 | 29 | #define TMR_RUNNING_MP 1 |
30 | #define TMR_RUNNING_MPR 2 | ||
29 | 31 | ||
30 | int mesh_allocated; | 32 | int mesh_allocated; |
31 | static struct kmem_cache *rm_cache; | 33 | static struct kmem_cache *rm_cache; |
@@ -354,6 +356,23 @@ static void ieee80211_mesh_path_timer(unsigned long data) | |||
354 | ieee80211_queue_work(&local->hw, &ifmsh->work); | 356 | ieee80211_queue_work(&local->hw, &ifmsh->work); |
355 | } | 357 | } |
356 | 358 | ||
359 | static void ieee80211_mesh_path_root_timer(unsigned long data) | ||
360 | { | ||
361 | struct ieee80211_sub_if_data *sdata = | ||
362 | (struct ieee80211_sub_if_data *) data; | ||
363 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
364 | struct ieee80211_local *local = sdata->local; | ||
365 | |||
366 | set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); | ||
367 | |||
368 | if (local->quiescing) { | ||
369 | set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running); | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | ieee80211_queue_work(&local->hw, &ifmsh->work); | ||
374 | } | ||
375 | |||
357 | /** | 376 | /** |
358 | * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame | 377 | * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame |
359 | * @hdr: 802.11 frame header | 378 | * @hdr: 802.11 frame header |
@@ -447,6 +466,15 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | |||
447 | round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); | 466 | round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); |
448 | } | 467 | } |
449 | 468 | ||
469 | static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) | ||
470 | { | ||
471 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
472 | |||
473 | mesh_path_tx_root_frame(sdata); | ||
474 | mod_timer(&ifmsh->mesh_path_root_timer, | ||
475 | round_jiffies(jiffies + IEEE80211_MESH_RANN_INTERVAL)); | ||
476 | } | ||
477 | |||
450 | #ifdef CONFIG_PM | 478 | #ifdef CONFIG_PM |
451 | void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) | 479 | void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) |
452 | { | 480 | { |
@@ -461,6 +489,8 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) | |||
461 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); | 489 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); |
462 | if (del_timer_sync(&ifmsh->mesh_path_timer)) | 490 | if (del_timer_sync(&ifmsh->mesh_path_timer)) |
463 | set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); | 491 | set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); |
492 | if (del_timer_sync(&ifmsh->mesh_path_root_timer)) | ||
493 | set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running); | ||
464 | } | 494 | } |
465 | 495 | ||
466 | void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) | 496 | void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) |
@@ -471,6 +501,8 @@ void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) | |||
471 | add_timer(&ifmsh->housekeeping_timer); | 501 | add_timer(&ifmsh->housekeeping_timer); |
472 | if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running)) | 502 | if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running)) |
473 | add_timer(&ifmsh->mesh_path_timer); | 503 | add_timer(&ifmsh->mesh_path_timer); |
504 | if (test_and_clear_bit(TMR_RUNNING_MPR, &ifmsh->timers_running)) | ||
505 | add_timer(&ifmsh->mesh_path_root_timer); | ||
474 | } | 506 | } |
475 | #endif | 507 | #endif |
476 | 508 | ||
@@ -490,6 +522,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
490 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | 522 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) |
491 | { | 523 | { |
492 | del_timer_sync(&sdata->u.mesh.housekeeping_timer); | 524 | del_timer_sync(&sdata->u.mesh.housekeeping_timer); |
525 | del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); | ||
493 | /* | 526 | /* |
494 | * If the timer fired while we waited for it, it will have | 527 | * If the timer fired while we waited for it, it will have |
495 | * requeued the work. Now the work will be running again | 528 | * requeued the work. Now the work will be running again |
@@ -627,6 +660,9 @@ static void ieee80211_mesh_work(struct work_struct *work) | |||
627 | 660 | ||
628 | if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) | 661 | if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) |
629 | ieee80211_mesh_housekeeping(sdata, ifmsh); | 662 | ieee80211_mesh_housekeeping(sdata, ifmsh); |
663 | |||
664 | if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags)) | ||
665 | ieee80211_mesh_rootpath(sdata); | ||
630 | } | 666 | } |
631 | 667 | ||
632 | void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) | 668 | void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) |
@@ -683,6 +719,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) | |||
683 | setup_timer(&ifmsh->mesh_path_timer, | 719 | setup_timer(&ifmsh->mesh_path_timer, |
684 | ieee80211_mesh_path_timer, | 720 | ieee80211_mesh_path_timer, |
685 | (unsigned long) sdata); | 721 | (unsigned long) sdata); |
722 | setup_timer(&ifmsh->mesh_path_root_timer, | ||
723 | ieee80211_mesh_path_root_timer, | ||
724 | (unsigned long) sdata); | ||
686 | INIT_LIST_HEAD(&ifmsh->preq_queue.list); | 725 | INIT_LIST_HEAD(&ifmsh->preq_queue.list); |
687 | spin_lock_init(&ifmsh->mesh_preq_queue_lock); | 726 | spin_lock_init(&ifmsh->mesh_preq_queue_lock); |
688 | } | 727 | } |