mesh.c (d585a021c0b10b0477d6b608c53e1feb8cde0507) mesh.c (5bb644a0fd25a5e083ecbfaa92a211db99aa6ef7)
1/*
2 * Copyright (c) 2008 open80211s Ltd.
3 * Authors: Luis Carlos Cobo <luisca@cozybit.com>
4 * Javier Cardona <javier@cozybit.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.

--- 7 unchanged lines hidden (view full) ---

16#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
17
18#define PP_OFFSET 1 /* Path Selection Protocol */
19#define PM_OFFSET 5 /* Path Selection Metric */
20#define CC_OFFSET 9 /* Congestion Control Mode */
21#define CAPAB_OFFSET 17
22#define ACCEPT_PLINKS 0x80
23
1/*
2 * Copyright (c) 2008 open80211s Ltd.
3 * Authors: Luis Carlos Cobo <luisca@cozybit.com>
4 * Javier Cardona <javier@cozybit.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.

--- 7 unchanged lines hidden (view full) ---

16#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
17
18#define PP_OFFSET 1 /* Path Selection Protocol */
19#define PM_OFFSET 5 /* Path Selection Metric */
20#define CC_OFFSET 9 /* Congestion Control Mode */
21#define CAPAB_OFFSET 17
22#define ACCEPT_PLINKS 0x80
23
24#define TMR_RUNNING_HK 0
25#define TMR_RUNNING_MP 1
26
24int mesh_allocated;
25static struct kmem_cache *rm_cache;
26
27void ieee80211s_init(void)
28{
29 mesh_pathtbl_init();
30 mesh_allocated = 1;
31 rm_cache = kmem_cache_create("mesh_rmc", sizeof(struct rmc_entry),

--- 8 unchanged lines hidden (view full) ---

40
41static void ieee80211_mesh_housekeeping_timer(unsigned long data)
42{
43 struct ieee80211_sub_if_data *sdata = (void *) data;
44 struct ieee80211_local *local = sdata->local;
45 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
46
47 ifmsh->housekeeping = true;
27int mesh_allocated;
28static struct kmem_cache *rm_cache;
29
30void ieee80211s_init(void)
31{
32 mesh_pathtbl_init();
33 mesh_allocated = 1;
34 rm_cache = kmem_cache_create("mesh_rmc", sizeof(struct rmc_entry),

--- 8 unchanged lines hidden (view full) ---

43
44static void ieee80211_mesh_housekeeping_timer(unsigned long data)
45{
46 struct ieee80211_sub_if_data *sdata = (void *) data;
47 struct ieee80211_local *local = sdata->local;
48 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
49
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);
49}
50
51/**
52 * mesh_matches_local - check if the config of a mesh point matches ours
53 *
54 * @ie: information elements of a management frame from the mesh peer
55 * @sdata: local mesh subif

--- 282 unchanged lines hidden (view full) ---

338
339static void ieee80211_mesh_path_timer(unsigned long data)
340{
341 struct ieee80211_sub_if_data *sdata =
342 (struct ieee80211_sub_if_data *) data;
343 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
344 struct ieee80211_local *local = sdata->local;
345
57 queue_work(local->hw.workqueue, &ifmsh->work);
58}
59
60/**
61 * mesh_matches_local - check if the config of a mesh point matches ours
62 *
63 * @ie: information elements of a management frame from the mesh peer
64 * @sdata: local mesh subif

--- 282 unchanged lines hidden (view full) ---

347
348static void ieee80211_mesh_path_timer(unsigned long data)
349{
350 struct ieee80211_sub_if_data *sdata =
351 (struct ieee80211_sub_if_data *) data;
352 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
353 struct ieee80211_local *local = sdata->local;
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);
347}
348
349struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
350{
351 struct mesh_table *newtbl;
352 struct hlist_head *oldhash;
353 struct hlist_node *p, *q;

--- 58 unchanged lines hidden (view full) ---

412 sdata->dev->name);
413#endif
414
415 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
416 mesh_path_expire(sdata);
417
418 free_plinks = mesh_plink_availables(sdata);
419 if (free_plinks != sdata->u.mesh.accepting_plinks)
360 queue_work(local->hw.workqueue, &ifmsh->work);
361}
362
363struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
364{
365 struct mesh_table *newtbl;
366 struct hlist_head *oldhash;
367 struct hlist_node *p, *q;

--- 58 unchanged lines hidden (view full) ---

426 sdata->dev->name);
427#endif
428
429 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
430 mesh_path_expire(sdata);
431
432 free_plinks = mesh_plink_availables(sdata);
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
422 ifmsh->housekeeping = false;
423 mod_timer(&ifmsh->housekeeping_timer,
424 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
425}
426
435
436 ifmsh->housekeeping = false;
437 mod_timer(&ifmsh->housekeeping_timer,
438 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
439}
440
441#ifdef CONFIG_PM
442void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
443{
444 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
427
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
457void 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
467
428void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
429{
430 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
431 struct ieee80211_local *local = sdata->local;
432
433 ifmsh->housekeeping = true;
434 queue_work(local->hw.workqueue, &ifmsh->work);
468void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
469{
470 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
471 struct ieee80211_local *local = sdata->local;
472
473 ifmsh->housekeeping = true;
474 queue_work(local->hw.workqueue, &ifmsh->work);
435 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
436 IEEE80211_IFCC_BEACON_ENABLED);
475 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
476 BSS_CHANGED_BEACON_ENABLED);
437}
438
439void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
440{
441 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
442 /*
443 * If the timer fired while we waited for it, it will have
444 * requeued the work. Now the work will be running again

--- 215 unchanged lines hidden ---
477}
478
479void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
480{
481 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
482 /*
483 * If the timer fired while we waited for it, it will have
484 * requeued the work. Now the work will be running again

--- 215 unchanged lines hidden ---