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

Commit 55335137 authored by Ashok Nagarajan's avatar Ashok Nagarajan Committed by John W. Linville
Browse files

{nl,cfg,mac}80211: Implement RSSI threshold for mesh peering



Mesh peer links are established only if average rssi of the peer
candidate satisfies the threshold. This is not in 802.11s specification
but was requested by David Fulgham, an open80211s user. This is a way to avoid
marginal peer links with stations that are barely within range.

This patch adds a new mesh configuration parameter, mesh_rssi_threshold. This
feature is supported only for hardwares that report signal in dBm.

Signed-off-by: default avatarAshok Nagarajan <ashok@cozybit.com>
Signed-off-by: default avatarJavier Cardona <javier@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 58098021
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -2112,6 +2112,10 @@ enum nl80211_mntr_flags {
 * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding
 * or forwarding entity (default is TRUE - forwarding entity)
 *
 * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the
 * threshold for average signal strength of candidate station to establish
 * a peer link.
 *
 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
 *
 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -2137,6 +2141,7 @@ enum nl80211_meshconf_params {
	NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
	NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
	NL80211_MESHCONF_FORWARDING,
	NL80211_MESHCONF_RSSI_THRESHOLD,

	/* keep last */
	__NL80211_MESHCONF_ATTR_AFTER_LAST,
+1 −0
Original line number Diff line number Diff line
@@ -809,6 +809,7 @@ struct mesh_config {
	 * Still keeping the same nomenclature to be in sync with the spec. */
	bool  dot11MeshGateAnnouncementProtocol;
	bool dot11MeshForwarding;
	s32 rssi_threshold;
};

/**
+8 −0
Original line number Diff line number Diff line
@@ -1314,6 +1314,14 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
	}
	if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
		conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
	if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
		/* our RSSI threshold implementation is supported only for
		 * devices that report signal in dBm.
		 */
		if (!(sdata->local->hw.flags & IEEE80211_HW_SIGNAL_DBM))
			return -ENOTSUPP;
		conf->rssi_threshold = nconf->rssi_threshold;
	}
	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -443,6 +443,7 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
		u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
#endif


@@ -581,6 +582,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
	MESHPARAMS_ADD(dot11MeshHWMPRootMode);
	MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
	MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
	MESHPARAMS_ADD(rssi_threshold);
#undef MESHPARAMS_ADD
}
#endif
+15 −1
Original line number Diff line number Diff line
@@ -31,6 +31,11 @@
#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)

#define sta_meets_rssi_threshold(sta, sdata) \
		(sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
		(s8) -ewma_read(&sta->avg_signal) > \
		sdata->u.mesh.mshcfg.rssi_threshold)

enum plink_event {
	PLINK_UNDEFINED,
	OPN_ACPT,
@@ -301,7 +306,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
	if (mesh_peer_accepts_plinks(elems) &&
			sta->plink_state == NL80211_PLINK_LISTEN &&
			sdata->u.mesh.accepting_plinks &&
			sdata->u.mesh.mshcfg.auto_open_plinks)
			sdata->u.mesh.mshcfg.auto_open_plinks &&
			sta_meets_rssi_threshold(sta, sdata))
		mesh_plink_open(sta);

	rcu_read_unlock();
@@ -531,6 +537,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
		return;
	}

	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
	    !sta_meets_rssi_threshold(sta, sdata)) {
		mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n",
			sta->sta.addr);
		rcu_read_unlock();
		return;
	}

	if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
		mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
		rcu_read_unlock();
Loading