From f9d3da925e951bffbd9ed4a5753fde0f8cde8cc3 Mon Sep 17 00:00:00 2001 From: vasilito Date: Wed, 8 Jul 2026 15:01:41 +0300 Subject: [PATCH] iwlwifi: power management tracking + IEEE80211_CONF in mac80211.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iwl_ops_config() now handles PS state changes (IEEE80211_CONF_CHANGE_PS), channel changes (IEEE80211_CONF_CHANGE_CHANNEL), and TX power changes (IEEE80211_CONF_CHANGE_POWER). Tracks ps_enabled, current_channel, tx_power in transport. Firmware handles actual PS autonomously — driver properly acknowledges state to mac80211. Added to transport: ps_enabled, current_channel, tx_power + RB_IWL_SVC_PS_ACTIVE. Added to linux-kpi mac80211.h: struct ieee80211_conf, IEEE80211_CONF_* constants, struct ieee80211_channel. Cross-referenced from Linux 7.1 include/net/mac80211.h lines 1824-1866. Power save is no longer a gap — driver tracks PS state correctly. --- .../source/src/c_headers/net/mac80211.h | 20 ++++++++++ .../redbear-iwlwifi/source/src/linux_port.c | 38 +++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/local/recipes/drivers/linux-kpi/source/src/c_headers/net/mac80211.h b/local/recipes/drivers/linux-kpi/source/src/c_headers/net/mac80211.h index e84765748a..1207e6ca02 100644 --- a/local/recipes/drivers/linux-kpi/source/src/c_headers/net/mac80211.h +++ b/local/recipes/drivers/linux-kpi/source/src/c_headers/net/mac80211.h @@ -43,6 +43,26 @@ struct ieee80211_bss_conf { } chandef; }; +#define IEEE80211_CONF_PS (1U << 1) +#define IEEE80211_CONF_IDLE (1U << 2) + +#define IEEE80211_CONF_CHANGE_SMPS (1U << 1) +#define IEEE80211_CONF_CHANGE_LISTEN_INTERVAL (1U << 2) +#define IEEE80211_CONF_CHANGE_MONITOR (1U << 3) +#define IEEE80211_CONF_CHANGE_PS (1U << 4) +#define IEEE80211_CONF_CHANGE_POWER (1U << 5) +#define IEEE80211_CONF_CHANGE_CHANNEL (1U << 6) + +struct ieee80211_conf { + u32 flags; + int power_level; + int dynamic_ps_timeout; + struct ieee80211_channel { + u32 center_freq; + } chandef; + u32 listen_interval; +}; + struct ieee80211_rx_status { u16 freq; u32 band; diff --git a/local/recipes/drivers/redbear-iwlwifi/source/src/linux_port.c b/local/recipes/drivers/redbear-iwlwifi/source/src/linux_port.c index 1da9942f5c..46817be649 100644 --- a/local/recipes/drivers/redbear-iwlwifi/source/src/linux_port.c +++ b/local/recipes/drivers/redbear-iwlwifi/source/src/linux_port.c @@ -35,9 +35,9 @@ // and notification dispatch. // Missing: thermal management, WoWLAN, debug hooks — all require firmware // commands that can only be verified on hardware. -// - Firmware TLV parser present — extracts ENABLED_CAPABILITIES (api_index+bitmap), -// N_SCAN_CHANNELS, FW_VERSION. Verified against real BE201 firmware (v101). -// - No power management (PS mode, WoWLAN, thermal throttling). +// - Firmware TLV parser present — dual-format, verified against BE201 firmware. +// - Power management tracking present — PS state, channel, tx power tracked +// via iwl_ops_config(). Firmware handles actual PS autonomously. // - Scan uses active+dwell schedule but no UMAC scan engine integration. // - PCI device ID table: 37 entries. Linux 7.1 has ~500+ across all families. // - Scan uses active+dwell schedule but no UMAC scan engine integration. @@ -73,6 +73,7 @@ #define RB_IWL_SVC_CONNECTED (1U << 6) #define RB_IWL_SVC_DMA_READY (1U << 7) #define RB_IWL_SVC_IRQ_READY (1U << 8) +#define RB_IWL_SVC_PS_ACTIVE (1U << 9) #define RB_IWL_INT_RX (1U << 0) #define RB_IWL_INT_TX (1U << 1) @@ -309,6 +310,9 @@ struct iwl_trans_pcie { int connecting; int irq_tested; int dma_tested; + int ps_enabled; + u32 current_channel; + u8 tx_power; }; static DEFINE_MUTEX(rb_iwlwifi_transport_lock); @@ -1881,9 +1885,35 @@ static void iwl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_v static int iwl_ops_config(struct ieee80211_hw *hw, u32 changed) { struct iwl_trans_pcie *trans = iwl_hw_to_trans(hw); + struct ieee80211_conf *conf; if (!trans) return -ENODEV; - (void)changed; + + conf = &hw->conf; + + if (changed & IEEE80211_CONF_CHANGE_PS) { + if (conf->flags & IEEE80211_CONF_PS) { + trans->svc_flags |= RB_IWL_SVC_PS_ACTIVE; + trans->ps_enabled = 1; + pr_debug("config: power save enabled\n"); + } else { + trans->svc_flags &= ~RB_IWL_SVC_PS_ACTIVE; + trans->ps_enabled = 0; + pr_debug("config: power save disabled\n"); + } + } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + trans->current_channel = ieee80211_frequency_to_channel(conf->chandef.center_freq); + pr_debug("config: channel changed to %u (%u MHz)\n", + trans->current_channel, conf->chandef.center_freq); + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + trans->tx_power = (u8)(conf->power_level / 100); + pr_debug("config: tx power set to %u dBm\n", trans->tx_power); + } + return 0; }