Commit 83bb3633 authored by Benjamin Berg's avatar Benjamin Berg Committed by Johannes Berg
Browse files

wifi: iwlwifi: mvm: skip short statistics window when updating EMLSR



The statistics are not synchronized with the time that we enter EMLSR.
This means that we can receive the statistic notification just after
having cleared the counters, causing us to immediately exit EMLSR again.

Fix this by checking that most of the time for the window has passed. If
that is not the case, ignore this window and wait for the next
notification.

Signed-off-by: default avatarBenjamin Berg <benjamin.berg@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20241227095718.0eb0f2044535.Ic2af92737ccfc873f3b6c228704238ebb9f983ca@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 193aa7ee
Loading
Loading
Loading
Loading
+0 −36
Original line number Diff line number Diff line
@@ -210,32 +210,6 @@ 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);
	}

	IWL_DEBUG_INFO(mvm, "MPDU counters are cleared\n");
}

static int iwl_mvm_esr_mode_active(struct iwl_mvm *mvm,
				   struct ieee80211_vif *vif)
{
@@ -269,13 +243,6 @@ static int iwl_mvm_esr_mode_active(struct iwl_mvm *mvm,
	else
		mvmvif->primary_link = __ffs(vif->active_links);

	/*
	 * 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);

	iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_ESR_LINK_UP,
			       NULL);

@@ -447,9 +414,6 @@ static int iwl_mvm_esr_mode_inactive(struct iwl_mvm *mvm,
			break;
	}

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

	iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_ESR_LINK_DOWN,
			       NULL);

+16 −0
Original line number Diff line number Diff line
@@ -962,6 +962,9 @@ iwl_mvm_stat_iterator_all_links(struct iwl_mvm *mvm,
#define SEC_LINK_MIN_TX 3000
#define SEC_LINK_MIN_RX 400

/* Accept a ~20% short window to avoid issues due to jitter */
#define IWL_MVM_TPT_MIN_COUNT_WINDOW (IWL_MVM_TPT_COUNT_WINDOW_SEC * HZ * 4 / 5)

static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
{
	struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
@@ -971,6 +974,7 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
	unsigned long sec_link_tx = 0, sec_link_rx = 0;
	u8 sec_link_tx_perc, sec_link_rx_perc;
	u8 sec_link;
	bool skip = false;

	lockdep_assert_held(&mvm->mutex);

@@ -1010,13 +1014,25 @@ static void iwl_mvm_update_esr_mode_tpt(struct iwl_mvm *mvm)
		/*
		 * In EMLSR we have statistics every 5 seconds, so we can reset
		 * the counters upon every statistics notification.
		 * The FW sends the notification regularly, but it will be
		 * misaligned at the start. Skipping the measurement if it is
		 * short will synchronize us.
		 */
		if (jiffies - mvmsta->mpdu_counters[q].window_start <
		    IWL_MVM_TPT_MIN_COUNT_WINDOW)
			skip = true;
		mvmsta->mpdu_counters[q].window_start = jiffies;
		memset(mvmsta->mpdu_counters[q].per_link, 0,
		       sizeof(mvmsta->mpdu_counters[q].per_link));

		spin_unlock_bh(&mvmsta->mpdu_counters[q].lock);
	}

	if (skip) {
		IWL_DEBUG_INFO(mvm, "MPDU statistics window was short\n");
		return;
	}

	IWL_DEBUG_INFO(mvm, "total Tx MPDUs: %ld. total Rx MPDUs: %ld\n",
		       total_tx, total_rx);