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

Commit d405fd8c authored by Gregory Greenman's avatar Gregory Greenman Committed by Johannes Berg
Browse files

mac80211: recalculate some sta parameters after insertion



Sometimes a station is added already in ASSOC state. For example,
in AP mode, when a client station didn't get assoc resp and sends
an assoc req again. If a station is inserted when its state is ASSOC
or higher, the min chandef and allow_p2p_go_ps should be recalculated
again after the insertion.

Before this patch the recalculation happened only in sta_info_move_state
which occurs before the insertion of the sta and thus even though
it calls ieee80211_recalc_min_chandef/_p2p_go_ps_allowed functions,
since sdata->local->sta_list is still empty at this point, it doesn't do
anything.

Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 65026002
Loading
Loading
Loading
Loading
+32 −25
Original line number Diff line number Diff line
@@ -515,6 +515,31 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local,
	return err;
}

static void
ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	bool allow_p2p_go_ps = sdata->vif.p2p;
	struct sta_info *sta;

	rcu_read_lock();
	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sdata != sta->sdata ||
		    !test_sta_flag(sta, WLAN_STA_ASSOC))
			continue;
		if (!sta->sta.support_p2p_ps) {
			allow_p2p_go_ps = false;
			break;
		}
	}
	rcu_read_unlock();

	if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) {
		sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps;
		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS);
	}
}

/*
 * should be called with sta_mtx locked
 * this function replaces the mutex lock
@@ -561,6 +586,13 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
		goto out_remove;

	set_sta_flag(sta, WLAN_STA_INSERTED);

	if (sta->sta_state >= IEEE80211_STA_ASSOC) {
		ieee80211_recalc_min_chandef(sta->sdata);
		if (!sta->sta.support_p2p_ps)
			ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
	}

	/* accept BA sessions now */
	clear_sta_flag(sta, WLAN_STA_BLOCK_BA);

@@ -1788,31 +1820,6 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
}
EXPORT_SYMBOL(ieee80211_sta_set_buffered);

static void
ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	bool allow_p2p_go_ps = sdata->vif.p2p;
	struct sta_info *sta;

	rcu_read_lock();
	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sdata != sta->sdata ||
		    !test_sta_flag(sta, WLAN_STA_ASSOC))
			continue;
		if (!sta->sta.support_p2p_ps) {
			allow_p2p_go_ps = false;
			break;
		}
	}
	rcu_read_unlock();

	if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) {
		sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps;
		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS);
	}
}

int sta_info_move_state(struct sta_info *sta,
			enum ieee80211_sta_state new_state)
{