Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e304bfd3 authored by Rui Paulo's avatar Rui Paulo Committed by John W. Linville
Browse files

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: default avatarRui Paulo <rpaulo@gmail.com>
Signed-off-by: default avatarJavier Cardona <javier@cozybit.com>
Reviewed-by: default avatarAndrey Yurovsky <andrey@cozybit.com>
Tested-by: default avatarBrian Cavagnolo <brian@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d19b3bf6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -355,6 +355,7 @@ struct ieee80211_if_mesh {
	struct work_struct work;
	struct timer_list housekeeping_timer;
	struct timer_list mesh_path_timer;
	struct timer_list mesh_path_root_timer;
	struct sk_buff_head skb_queue;

	unsigned long timers_running;
+39 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
#define IEEE80211_MESH_RANN_INTERVAL	     (1 * HZ)

#define MESHCONF_PP_OFFSET 	0		/* Path Selection Protocol */
#define MESHCONF_PM_OFFSET	1		/* Path Selection Metric   */
@@ -26,6 +27,7 @@

#define TMR_RUNNING_HK	0
#define TMR_RUNNING_MP	1
#define TMR_RUNNING_MPR	2

int mesh_allocated;
static struct kmem_cache *rm_cache;
@@ -354,6 +356,23 @@ static void ieee80211_mesh_path_timer(unsigned long data)
	ieee80211_queue_work(&local->hw, &ifmsh->work);
}

static void ieee80211_mesh_path_root_timer(unsigned long data)
{
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
	struct ieee80211_local *local = sdata->local;

	set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);

	if (local->quiescing) {
		set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
		return;
	}

	ieee80211_queue_work(&local->hw, &ifmsh->work);
}

/**
 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
 * @hdr:    	802.11 frame header
@@ -447,6 +466,15 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
		  round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
}

static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;

	mesh_path_tx_root_frame(sdata);
	mod_timer(&ifmsh->mesh_path_root_timer,
		  round_jiffies(jiffies + IEEE80211_MESH_RANN_INTERVAL));
}

#ifdef CONFIG_PM
void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
{
@@ -461,6 +489,8 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
		set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
	if (del_timer_sync(&ifmsh->mesh_path_timer))
		set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
	if (del_timer_sync(&ifmsh->mesh_path_root_timer))
		set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
}

void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
@@ -471,6 +501,8 @@ void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
		add_timer(&ifmsh->housekeeping_timer);
	if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running))
		add_timer(&ifmsh->mesh_path_timer);
	if (test_and_clear_bit(TMR_RUNNING_MPR, &ifmsh->timers_running))
		add_timer(&ifmsh->mesh_path_root_timer);
}
#endif

@@ -490,6 +522,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
{
	del_timer_sync(&sdata->u.mesh.housekeeping_timer);
	del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
	/*
	 * If the timer fired while we waited for it, it will have
	 * requeued the work. Now the work will be running again
@@ -627,6 +660,9 @@ static void ieee80211_mesh_work(struct work_struct *work)

	if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
		ieee80211_mesh_housekeeping(sdata, ifmsh);

	if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
		ieee80211_mesh_rootpath(sdata);
}

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)
	setup_timer(&ifmsh->mesh_path_timer,
		    ieee80211_mesh_path_timer,
		    (unsigned long) sdata);
	setup_timer(&ifmsh->mesh_path_root_timer,
		    ieee80211_mesh_path_root_timer,
		    (unsigned long) sdata);
	INIT_LIST_HEAD(&ifmsh->preq_queue.list);
	spin_lock_init(&ifmsh->mesh_preq_queue_lock);
}
+3 −0
Original line number Diff line number Diff line
@@ -53,11 +53,13 @@ enum mesh_path_flags {
 * to grow.
 * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
 * grow
 * @MESH_WORK_ROOT: the mesh root station needs to send a frame
 */
enum mesh_deferred_task_flags {
	MESH_WORK_HOUSEKEEPING,
	MESH_WORK_GROW_MPATH_TABLE,
	MESH_WORK_GROW_MPP_TABLE,
	MESH_WORK_ROOT,
};

/**
@@ -294,6 +296,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
		struct ieee80211_sub_if_data *sdata);
void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);

extern int mesh_paths_generation;

+11 −0
Original line number Diff line number Diff line
@@ -1003,3 +1003,14 @@ void mesh_path_timer(unsigned long data)
endmpathtimer:
	rcu_read_unlock();
}

void
mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;

	mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->dev->dev_addr,
			       cpu_to_le32(++ifmsh->sn),
			       0, NULL, 0, sdata->dev->broadcast,
			       0, MESH_TTL, 0, 0, 0, sdata);
}