mesh.c (074d46d1d23f27488a3f314e29cae2453541f17d) mesh.c (dbf498fbafa2c23139d5a990e94ed78bafbbea19)
1/*
2 * Copyright (c) 2008, 2009 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.
9 */
10
11#include <linux/slab.h>
12#include <asm/unaligned.h>
13#include "ieee80211_i.h"
14#include "mesh.h"
15
1/*
2 * Copyright (c) 2008, 2009 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.
9 */
10
11#include <linux/slab.h>
12#include <asm/unaligned.h>
13#include "ieee80211_i.h"
14#include "mesh.h"
15
16#define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01
17#define MESHCONF_CAPAB_FORWARDING 0x08
18
19#define TMR_RUNNING_HK 0
20#define TMR_RUNNING_MP 1
21#define TMR_RUNNING_MPR 2
22
23int mesh_allocated;
24static struct kmem_cache *rm_cache;
25
26#ifdef CONFIG_MAC80211_MESH

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

246 /* Mesh Formation Info - number of neighbors */
247 neighbors = atomic_read(&ifmsh->mshstats.estab_plinks);
248 /* Number of neighbor mesh STAs or 15 whichever is smaller */
249 neighbors = (neighbors > 15) ? 15 : neighbors;
250 *pos++ = neighbors << 1;
251 /* Mesh capability */
252 ifmsh->accepting_plinks = mesh_plink_availables(sdata);
253 *pos = MESHCONF_CAPAB_FORWARDING;
16#define TMR_RUNNING_HK 0
17#define TMR_RUNNING_MP 1
18#define TMR_RUNNING_MPR 2
19
20int mesh_allocated;
21static struct kmem_cache *rm_cache;
22
23#ifdef CONFIG_MAC80211_MESH

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

243 /* Mesh Formation Info - number of neighbors */
244 neighbors = atomic_read(&ifmsh->mshstats.estab_plinks);
245 /* Number of neighbor mesh STAs or 15 whichever is smaller */
246 neighbors = (neighbors > 15) ? 15 : neighbors;
247 *pos++ = neighbors << 1;
248 /* Mesh capability */
249 ifmsh->accepting_plinks = mesh_plink_availables(sdata);
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;
257
258 return 0;
259}
260
261int
262mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
263{

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

568 struct ieee80211_local *local = sdata->local;
569
570 local->fif_other_bss++;
571 /* mesh ifaces must set allmulti to forward mcast traffic */
572 atomic_inc(&local->iff_allmultis);
573 ieee80211_configure_filter(local);
574
575 ifmsh->mesh_cc_id = 0; /* Disabled */
255 *pos++ = 0x00;
256
257 return 0;
258}
259
260int
261mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
262{

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

567 struct ieee80211_local *local = sdata->local;
568
569 local->fif_other_bss++;
570 /* mesh ifaces must set allmulti to forward mcast traffic */
571 atomic_inc(&local->iff_allmultis);
572 ieee80211_configure_filter(local);
573
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);
579 ieee80211_mesh_root_setup(ifmsh);
580 ieee80211_queue_work(&local->hw, &sdata->work);
581 sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
582 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
583 BSS_CHANGED_BEACON_ENABLED |
584 BSS_CHANGED_BEACON_INT);
585}

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

611
612static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
613 u16 stype,
614 struct ieee80211_mgmt *mgmt,
615 size_t len,
616 struct ieee80211_rx_status *rx_status)
617{
618 struct ieee80211_local *local = sdata->local;
580 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
581 ieee80211_mesh_root_setup(ifmsh);
582 ieee80211_queue_work(&local->hw, &sdata->work);
583 sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
584 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
585 BSS_CHANGED_BEACON_ENABLED |
586 BSS_CHANGED_BEACON_INT);
587}

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

613
614static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
615 u16 stype,
616 struct ieee80211_mgmt *mgmt,
617 size_t len,
618 struct ieee80211_rx_status *rx_status)
619{
620 struct ieee80211_local *local = sdata->local;
621 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
619 struct ieee802_11_elems elems;
620 struct ieee80211_channel *channel;
621 u32 supp_rates = 0;
622 size_t baselen;
623 int freq;
624 enum ieee80211_band band = rx_status->band;
625
626 /* ignore ProbeResp to foreign address */

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

649 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
650 return;
651
652 if (elems.mesh_id && elems.mesh_config &&
653 mesh_matches_local(&elems, sdata)) {
654 supp_rates = ieee80211_sta_get_rates(local, &elems, band);
655 mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems);
656 }
622 struct ieee802_11_elems elems;
623 struct ieee80211_channel *channel;
624 u32 supp_rates = 0;
625 size_t baselen;
626 int freq;
627 enum ieee80211_band band = rx_status->band;
628
629 /* ignore ProbeResp to foreign address */

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

652 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
653 return;
654
655 if (elems.mesh_id && elems.mesh_config &&
656 mesh_matches_local(&elems, sdata)) {
657 supp_rates = ieee80211_sta_get_rates(local, &elems, band);
658 mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems);
659 }
660
661 if (ifmsh->sync_ops)
662 ifmsh->sync_ops->rx_bcn_presp(sdata,
663 stype, mgmt, &elems, rx_status);
657}
658
659static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
660 struct ieee80211_mgmt *mgmt,
661 size_t len,
662 struct ieee80211_rx_status *rx_status)
663{
664 switch (mgmt->u.action.category) {

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

716 if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags))
717 mesh_mpp_table_grow();
718
719 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
720 ieee80211_mesh_housekeeping(sdata, ifmsh);
721
722 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
723 ieee80211_mesh_rootpath(sdata);
664}
665
666static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
667 struct ieee80211_mgmt *mgmt,
668 size_t len,
669 struct ieee80211_rx_status *rx_status)
670{
671 switch (mgmt->u.action.category) {

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

723 if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags))
724 mesh_mpp_table_grow();
725
726 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
727 ieee80211_mesh_housekeeping(sdata, ifmsh);
728
729 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
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}
725
726void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
727{
728 struct ieee80211_sub_if_data *sdata;
729
730 rcu_read_lock();
731 list_for_each_entry_rcu(sdata, &local->interfaces, list)

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

756 setup_timer(&ifmsh->mesh_path_timer,
757 ieee80211_mesh_path_timer,
758 (unsigned long) sdata);
759 setup_timer(&ifmsh->mesh_path_root_timer,
760 ieee80211_mesh_path_root_timer,
761 (unsigned long) sdata);
762 INIT_LIST_HEAD(&ifmsh->preq_queue.list);
763 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
734}
735
736void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
737{
738 struct ieee80211_sub_if_data *sdata;
739
740 rcu_read_lock();
741 list_for_each_entry_rcu(sdata, &local->interfaces, list)

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

766 setup_timer(&ifmsh->mesh_path_timer,
767 ieee80211_mesh_path_timer,
768 (unsigned long) sdata);
769 setup_timer(&ifmsh->mesh_path_root_timer,
770 ieee80211_mesh_path_root_timer,
771 (unsigned long) sdata);
772 INIT_LIST_HEAD(&ifmsh->preq_queue.list);
773 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
774 spin_lock_init(&ifmsh->sync_offset_lock);
764}
775}