diff options
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r-- | net/mac80211/mesh.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 9a3e5de0410a..fc712e60705d 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -21,6 +21,9 @@ | |||
21 | #define CAPAB_OFFSET 17 | 21 | #define CAPAB_OFFSET 17 |
22 | #define ACCEPT_PLINKS 0x80 | 22 | #define ACCEPT_PLINKS 0x80 |
23 | 23 | ||
24 | #define TMR_RUNNING_HK 0 | ||
25 | #define TMR_RUNNING_MP 1 | ||
26 | |||
24 | int mesh_allocated; | 27 | int mesh_allocated; |
25 | static struct kmem_cache *rm_cache; | 28 | static struct kmem_cache *rm_cache; |
26 | 29 | ||
@@ -45,6 +48,12 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data) | |||
45 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 48 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
46 | 49 | ||
47 | ifmsh->housekeeping = true; | 50 | ifmsh->housekeeping = true; |
51 | |||
52 | if (local->quiescing) { | ||
53 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); | ||
54 | return; | ||
55 | } | ||
56 | |||
48 | queue_work(local->hw.workqueue, &ifmsh->work); | 57 | queue_work(local->hw.workqueue, &ifmsh->work); |
49 | } | 58 | } |
50 | 59 | ||
@@ -343,6 +352,11 @@ static void ieee80211_mesh_path_timer(unsigned long data) | |||
343 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 352 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
344 | struct ieee80211_local *local = sdata->local; | 353 | struct ieee80211_local *local = sdata->local; |
345 | 354 | ||
355 | if (local->quiescing) { | ||
356 | set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); | ||
357 | return; | ||
358 | } | ||
359 | |||
346 | queue_work(local->hw.workqueue, &ifmsh->work); | 360 | queue_work(local->hw.workqueue, &ifmsh->work); |
347 | } | 361 | } |
348 | 362 | ||
@@ -417,13 +431,39 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | |||
417 | 431 | ||
418 | free_plinks = mesh_plink_availables(sdata); | 432 | free_plinks = mesh_plink_availables(sdata); |
419 | if (free_plinks != sdata->u.mesh.accepting_plinks) | 433 | if (free_plinks != sdata->u.mesh.accepting_plinks) |
420 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); | 434 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
421 | 435 | ||
422 | ifmsh->housekeeping = false; | 436 | ifmsh->housekeeping = false; |
423 | mod_timer(&ifmsh->housekeeping_timer, | 437 | mod_timer(&ifmsh->housekeeping_timer, |
424 | round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); | 438 | round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); |
425 | } | 439 | } |
426 | 440 | ||
441 | #ifdef CONFIG_PM | ||
442 | void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) | ||
443 | { | ||
444 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
445 | |||
446 | /* might restart the timer but that doesn't matter */ | ||
447 | cancel_work_sync(&ifmsh->work); | ||
448 | |||
449 | /* use atomic bitops in case both timers fire at the same time */ | ||
450 | |||
451 | if (del_timer_sync(&ifmsh->housekeeping_timer)) | ||
452 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); | ||
453 | if (del_timer_sync(&ifmsh->mesh_path_timer)) | ||
454 | set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); | ||
455 | } | ||
456 | |||
457 | void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) | ||
458 | { | ||
459 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
460 | |||
461 | if (test_and_clear_bit(TMR_RUNNING_HK, &ifmsh->timers_running)) | ||
462 | add_timer(&ifmsh->housekeeping_timer); | ||
463 | if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running)) | ||
464 | add_timer(&ifmsh->mesh_path_timer); | ||
465 | } | ||
466 | #endif | ||
427 | 467 | ||
428 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | 468 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) |
429 | { | 469 | { |
@@ -432,8 +472,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
432 | 472 | ||
433 | ifmsh->housekeeping = true; | 473 | ifmsh->housekeeping = true; |
434 | queue_work(local->hw.workqueue, &ifmsh->work); | 474 | queue_work(local->hw.workqueue, &ifmsh->work); |
435 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | | 475 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | |
436 | IEEE80211_IFCC_BEACON_ENABLED); | 476 | BSS_CHANGED_BEACON_ENABLED); |
437 | } | 477 | } |
438 | 478 | ||
439 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | 479 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) |