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

Commit 426001a6 authored by Eliad Peller's avatar Eliad Peller Committed by Luciano Coelho
Browse files

wlcore: use sta_state-based ROCs for AP mode



Try an opportunistic ROC when a STA is first added and stop the ROC when
the STA is removed or successfully authenticated. This would ensure we
don't miss auth/assoc/EAPOL packets during connection

Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent de40750f
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -4486,6 +4486,45 @@ static int wl12xx_sta_remove(struct wl1271 *wl,
	return ret;
}

static void wlcore_roc_if_possible(struct wl1271 *wl,
				   struct wl12xx_vif *wlvif)
{
	if (find_first_bit(wl->roc_map,
			   WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES)
		return;

	if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID))
		return;

	wl12xx_roc(wl, wlvif, wlvif->role_id, wlvif->band, wlvif->channel);
}

static void wlcore_update_inconn_sta(struct wl1271 *wl,
				     struct wl12xx_vif *wlvif,
				     struct wl1271_station *wl_sta,
				     bool in_connection)
{
	if (in_connection) {
		if (WARN_ON(wl_sta->in_connection))
			return;
		wl_sta->in_connection = true;
		if (!wlvif->inconn_count++)
			wlcore_roc_if_possible(wl, wlvif);
	} else {
		if (!wl_sta->in_connection)
			return;

		wl_sta->in_connection = false;
		wlvif->inconn_count--;
		if (WARN_ON(wlvif->inconn_count < 0))
			return;

		if (!wlvif->inconn_count)
			if (test_bit(wlvif->role_id, wl->roc_map))
				wl12xx_croc(wl, wlvif->role_id);
	}
}

static int wl12xx_update_sta_state(struct wl1271 *wl,
				   struct wl12xx_vif *wlvif,
				   struct ieee80211_sta *sta,
@@ -4508,6 +4547,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
		ret = wl12xx_sta_add(wl, wlvif, sta);
		if (ret)
			return ret;

		wlcore_update_inconn_sta(wl, wlvif, wl_sta, true);
	}

	/* Remove station (AP mode) */
@@ -4516,6 +4557,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
	    new_state == IEEE80211_STA_NOTEXIST) {
		/* must not fail */
		wl12xx_sta_remove(wl, wlvif, sta);

		wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
	}

	/* Authorize station (AP mode) */
@@ -4529,6 +4572,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
						     hlid);
		if (ret)
			return ret;

		wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
	}

	/* Authorize station */
+4 −0
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ struct wl12xx_rx_filter {

struct wl1271_station {
	u8 hlid;
	bool in_connection;
};

struct wl12xx_vif {
@@ -425,6 +426,9 @@ struct wl12xx_vif {
	struct delayed_work channel_switch_work;
	struct delayed_work connection_loss_work;

	/* number of in connection stations */
	int inconn_count;

	/*
	 * This struct must be last!
	 * data that has to be saved acrossed reconfigs (e.g. recovery)