drivers/net/wireless/intel/iwlwifi/mld/low_latency.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/mld/low_latency.c
Extension
.c
Size
8920 bytes
Lines
342
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * Copyright (C) 2024-2026 Intel Corporation
 */
#include "mld.h"
#include "iface.h"
#include "low_latency.h"
#include "hcmd.h"
#include "power.h"
#include "mlo.h"

#define MLD_LL_WK_INTERVAL_MSEC 500
#define MLD_LL_PERIOD (HZ * MLD_LL_WK_INTERVAL_MSEC / 1000)
#define MLD_LL_ACTIVE_WK_PERIOD (HZ * 10)

/* packets/MLD_LL_WK_PERIOD seconds */
#define MLD_LL_ENABLE_THRESH 100

static bool iwl_mld_calc_low_latency(struct iwl_mld *mld,
				     unsigned long timestamp)
{
	struct iwl_mld_low_latency *ll = &mld->low_latency;
	bool global_low_latency = false;
	u8 num_rx_q = mld->trans->info.num_rxqs;

	for (int mac_id = 0; mac_id < NUM_MAC_INDEX_DRIVER; mac_id++) {
		u32 total_vo_vi_pkts = 0;
		bool ll_period_expired;

		/* If it's not initialized yet, it means we have not yet
		 * received/transmitted any vo/vi packet on this MAC.
		 */
		if (!ll->window_start[mac_id])
			continue;

		ll_period_expired =
			time_after(timestamp, ll->window_start[mac_id] +
				   MLD_LL_ACTIVE_WK_PERIOD);

		if (ll_period_expired)
			ll->window_start[mac_id] = timestamp;

		for (int q = 0; q < num_rx_q; q++) {
			struct iwl_mld_low_latency_packets_counters *counters =
				&mld->low_latency.pkts_counters[q];

			spin_lock_bh(&counters->lock);

			total_vo_vi_pkts += counters->vo_vi[mac_id];

			if (ll_period_expired)
				counters->vo_vi[mac_id] = 0;

			spin_unlock_bh(&counters->lock);
		}

		/* enable immediately with enough packets but defer
		 * disabling only if the low-latency period expired and
		 * below threshold.
		 */
		if (total_vo_vi_pkts > MLD_LL_ENABLE_THRESH)
			mld->low_latency.result[mac_id] = true;
		else if (ll_period_expired)
			mld->low_latency.result[mac_id] = false;

		global_low_latency |= mld->low_latency.result[mac_id];
	}

	return global_low_latency;
}

static void iwl_mld_low_latency_iter(void *_data, u8 *mac,
				     struct ieee80211_vif *vif)
{
	struct iwl_mld *mld = _data;
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	bool prev = mld_vif->low_latency_causes & LOW_LATENCY_TRAFFIC;
	bool low_latency;

	if (!iwl_mld_vif_fw_id_valid(mld_vif))
		return;

	BUILD_BUG_ON(ARRAY_SIZE(mld->fw_id_to_vif) !=
		     ARRAY_SIZE(mld->low_latency.result));

	low_latency = mld->low_latency.result[mld_vif->fw_id];

	if (prev != low_latency)
		iwl_mld_vif_update_low_latency(mld, vif, low_latency,
					       LOW_LATENCY_TRAFFIC);

Annotation

Implementation Notes