Commit ec0d43d2 authored by Miri Korenblit's avatar Miri Korenblit Committed by Johannes Berg
Browse files

wifi: iwlwifi: mvm: Activate EMLSR based on traffic volume



Adjust EMLSR activation to account for traffic levels. By
tracking the number of RX/TX MPDUs, EMLSR will be activated only when
traffic volume meets the required threshold.

Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240505091420.9480f99ac8fc.If9eb946e929a39e10fe5f4638bc8bc3f8976edf1@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 1d52e8ca
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#define IWL_MVM_BT_COEX_ENABLE_ESR_THRESH	63
#define IWL_MVM_BT_COEX_WIFI_LOSS_THRESH	0
#define IWL_MVM_TRIGGER_LINK_SEL_TIME_SEC	30
#define IWL_MVM_TPT_COUNT_WINDOW_SEC		5

#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT	(100 * USEC_PER_MSEC)
#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT	(100 * USEC_PER_MSEC)
@@ -135,4 +136,5 @@
#define IWL_MVM_HIGH_RSSI_THRESH_160MHZ		-58
#define IWL_MVM_LOW_RSSI_THRESH_160MHZ		-61

#define IWL_MVM_ENTER_ESR_TPT_THRESH		400
#endif /* __MVM_CONSTANTS_H */
+21 −0
Original line number Diff line number Diff line
@@ -1639,6 +1639,18 @@ static void iwl_mvm_mlo_int_scan_wk(struct wiphy *wiphy, struct wiphy_work *wk)
	mutex_unlock(&mvmvif->mvm->mutex);
}

static void iwl_mvm_unblock_esr_tpt(struct wiphy *wiphy, struct wiphy_work *wk)
{
	struct iwl_mvm_vif *mvmvif =
		container_of(wk, struct iwl_mvm_vif, unblock_esr_tpt_wk);
	struct iwl_mvm *mvm = mvmvif->mvm;
	struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm);

	mutex_lock(&mvm->mutex);
	iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TPT);
	mutex_unlock(&mvm->mutex);
}

void iwl_mvm_mac_init_mvmvif(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif)
{
	lockdep_assert_held(&mvm->mutex);
@@ -1654,6 +1666,9 @@ void iwl_mvm_mac_init_mvmvif(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvmvif)

	wiphy_delayed_work_init(&mvmvif->mlo_int_scan_wk,
				iwl_mvm_mlo_int_scan_wk);

	wiphy_work_init(&mvmvif->unblock_esr_tpt_wk,
			iwl_mvm_unblock_esr_tpt);
}

static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
@@ -1803,6 +1818,8 @@ void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
	wiphy_delayed_work_cancel(mvm->hw->wiphy,
				  &mvmvif->mlo_int_scan_wk);

	wiphy_work_cancel(mvm->hw->wiphy, &mvmvif->unblock_esr_tpt_wk);

	cancel_delayed_work_sync(&mvmvif->csa_work);
}

@@ -3930,6 +3947,8 @@ iwl_mvm_sta_state_assoc_to_authorized(struct iwl_mvm *mvm,
		memset(&mvmvif->last_esr_exit, 0,
		       sizeof(mvmvif->last_esr_exit));

		iwl_mvm_block_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TPT, 0);

		/* when client is authorized (AP station marked as such),
		 * try to enable the best link(s).
		 */
@@ -3990,6 +4009,8 @@ iwl_mvm_sta_state_authorized_to_assoc(struct iwl_mvm *mvm,
		wiphy_delayed_work_cancel(mvm->hw->wiphy,
					  &mvmvif->mlo_int_scan_wk);

		wiphy_work_cancel(mvm->hw->wiphy, &mvmvif->unblock_esr_tpt_wk);

		/* No need for the periodic statistics anymore */
		if (ieee80211_vif_is_mld(vif) && mvmvif->esr_active)
			iwl_mvm_request_periodic_system_statistics(mvm, false);
+34 −0
Original line number Diff line number Diff line
@@ -207,6 +207,30 @@ static unsigned int iwl_mvm_mld_count_active_links(struct iwl_mvm_vif *mvmvif)
	return n_active;
}

static void iwl_mvm_restart_mpdu_count(struct iwl_mvm *mvm,
				       struct iwl_mvm_vif *mvmvif)
{
	struct ieee80211_sta *ap_sta = mvmvif->ap_sta;
	struct iwl_mvm_sta *mvmsta;

	lockdep_assert_held(&mvm->mutex);

	if (!ap_sta)
		return;

	mvmsta = iwl_mvm_sta_from_mac80211(ap_sta);
	if (!mvmsta->mpdu_counters)
		return;

	for (int q = 0; q < mvm->trans->num_rx_queues; q++) {
		spin_lock_bh(&mvmsta->mpdu_counters[q].lock);
		memset(mvmsta->mpdu_counters[q].per_link, 0,
		       sizeof(mvmsta->mpdu_counters[q].per_link));
		mvmsta->mpdu_counters[q].window_start = jiffies;
		spin_unlock_bh(&mvmsta->mpdu_counters[q].lock);
	}
}

static int iwl_mvm_esr_mode_active(struct iwl_mvm *mvm,
				   struct ieee80211_vif *vif)
{
@@ -243,6 +267,13 @@ static int iwl_mvm_esr_mode_active(struct iwl_mvm *mvm,
	/* Needed for tracking RSSI */
	iwl_mvm_request_periodic_system_statistics(mvm, true);

	/*
	 * Restart the MPDU counters and the counting window, so when the
	 * statistics arrive (which is where we look at the counters) we
	 * will be at the end of the window.
	 */
	iwl_mvm_restart_mpdu_count(mvm, mvmvif);

	return ret;
}

@@ -412,6 +443,9 @@ static int iwl_mvm_esr_mode_inactive(struct iwl_mvm *mvm,

	iwl_mvm_request_periodic_system_statistics(mvm, false);

	/* Start a new counting window */
	iwl_mvm_restart_mpdu_count(mvm, mvmvif);

	return ret;
}

+3 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * Copyright (C) 2022-2023 Intel Corporation
 * Copyright (C) 2022-2024 Intel Corporation
 */
#include "mvm.h"
#include "time-sync.h"
@@ -723,7 +723,6 @@ int iwl_mvm_mld_add_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			iwl_mvm_mld_set_ap_sta_id(sta, mvm_vif->link[link_id],
						  mvm_link_sta);
	}

	return 0;

err:
@@ -849,6 +848,8 @@ int iwl_mvm_mld_rm_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, mvm_link_sta,
					  link_id, stay_in_fw);
	}
	kfree(mvm_sta->mpdu_counters);
	mvm_sta->mpdu_counters = NULL;

	return ret;
}
+4 −0
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ struct iwl_mvm_vif_link_info {
 * @IWL_MVM_ESR_BLOCKED_PREVENTION: Prevent EMLSR to avoid entering and exiting
 *	in a loop.
 * @IWL_MVM_ESR_BLOCKED_WOWLAN: WOWLAN is preventing the enablement of EMLSR
 * @IWL_MVM_ESR_BLOCKED_TPT: block EMLSR when there is not enough traffic
 * @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons
 * @IWL_MVM_ESR_EXIT_LOW_RSSI: link is deactivated/not allowed for EMLSR
 *	due to low RSSI.
@@ -365,6 +366,7 @@ struct iwl_mvm_vif_link_info {
enum iwl_mvm_esr_state {
	IWL_MVM_ESR_BLOCKED_PREVENTION	= 0x1,
	IWL_MVM_ESR_BLOCKED_WOWLAN	= 0x2,
	IWL_MVM_ESR_BLOCKED_TPT		= 0x4,
	IWL_MVM_ESR_EXIT_MISSED_BEACON	= 0x10000,
	IWL_MVM_ESR_EXIT_LOW_RSSI	= 0x20000,
	IWL_MVM_ESR_EXIT_COEX		= 0x40000,
@@ -430,6 +432,7 @@ struct iwl_mvm_esr_exit {
 *	&IWL_MVM_ESR_PREVENT_REASONS.
 * @prevent_esr_done_wk: work that should be done when esr prevention ends.
 * @mlo_int_scan_wk: work for the internal MLO scan.
 * @unblock_esr_tpt_wk: work for unblocking EMLSR when tpt is high enough.
 */
struct iwl_mvm_vif {
	struct iwl_mvm *mvm;
@@ -527,6 +530,7 @@ struct iwl_mvm_vif {
	u8 exit_same_reason_count;
	struct wiphy_delayed_work prevent_esr_done_wk;
	struct wiphy_delayed_work mlo_int_scan_wk;
	struct wiphy_work unblock_esr_tpt_wk;

	struct iwl_mvm_vif_link_info deflink;
	struct iwl_mvm_vif_link_info *link[IEEE80211_MLD_MAX_NUM_LINKS];
Loading