diff options
author | Miri Korenblit <miriam.rachel.korenblit@intel.com> | 2025-03-09 07:36:40 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2025-03-11 16:29:24 +0100 |
commit | cb9716eae2dfac2f70fea19df928e61bed314ce9 (patch) | |
tree | 22af12e6546e9f0b688efdb939148445a08ae655 | |
parent | 834bfc698bf7cee3bf61c0209b410c7f97a54108 (diff) |
wifi: iwlwifi: mld: fix SMPS W/A
If the user disables power save of a vif that didn't have it enabled
(for example before association), mac80211 will not notify the driver
with BSS_CHANGED_PS. This will cause the driver to not update the
device-level power save to disabled.
Fix this by checking the vif's power save status upon authorization, and
stop considering the vif's power save status on disassociation.
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250309073442.1cdeb78b19ba.I58fe02c062524029071b04b093a1b09c5e46f4ef@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/iface.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/power.c | 3 |
3 files changed, 24 insertions, 6 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/iface.h b/drivers/net/wireless/intel/iwlwifi/mld/iface.h index 2c928113f6802..57910660ed186 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/iface.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/iface.h @@ -134,6 +134,7 @@ struct iwl_mld_emlsr { * @beacon_inject_active: indicates an active debugfs beacon ie injection * @low_latency_causes: bit flags, indicating the causes for low-latency, * see @iwl_mld_low_latency_cause. + * @ps_disabled: indicates that PS is disabled for this interface * @mld: pointer to the mld structure. * @deflink: default link data, for use in non-MLO, * @link: reference to link data for each valid link, for use in MLO. @@ -159,6 +160,7 @@ struct iwl_mld_vif { bool beacon_inject_active; #endif u8 low_latency_causes; + bool ps_disabled; ); /* And here fields that survive a fw restart */ struct iwl_mld *mld; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c index d73bd0179f7dc..ba149581e25d4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c @@ -1262,6 +1262,23 @@ iwl_mld_mac80211_link_info_changed(struct ieee80211_hw *hw, iwl_mld_set_tx_power(mld, link_conf, link_conf->txpower); } +static void +iwl_mld_smps_wa(struct iwl_mld *mld, struct ieee80211_vif *vif, bool enable) +{ + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); + + /* Send the device-level power commands since the + * firmware checks the POWER_TABLE_CMD's POWER_SAVE_EN bit to + * determine SMPS mode. + */ + if (mld_vif->ps_disabled == !enable) + return; + + mld_vif->ps_disabled = !enable; + + iwl_mld_update_device_power(mld, false); +} + static void iwl_mld_mac80211_vif_cfg_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -1295,11 +1312,7 @@ void iwl_mld_mac80211_vif_cfg_changed(struct ieee80211_hw *hw, } if (changes & BSS_CHANGED_PS) { - /* Send both device-level and MAC-level power commands since the - * firmware checks the POWER_TABLE_CMD's POWER_SAVE_EN bit to - * determine SMPS mode. - */ - iwl_mld_update_device_power(mld, false); + iwl_mld_smps_wa(mld, vif, vif->cfg.ps); iwl_mld_update_mac_power(mld, vif, false); } @@ -1716,6 +1729,7 @@ static int iwl_mld_move_sta_state_up(struct iwl_mld *mld, FW_CTXT_ACTION_MODIFY); if (ret) return ret; + iwl_mld_smps_wa(mld, vif, vif->cfg.ps); } /* MFP is set by default before the station is authorized. @@ -1758,6 +1772,7 @@ static int iwl_mld_move_sta_state_down(struct iwl_mld *mld, &mld_vif->emlsr.check_tpt_wk); iwl_mld_reset_cca_40mhz_workaround(mld, vif); + iwl_mld_smps_wa(mld, vif, true); } /* once we move into assoc state, need to update the FW to diff --git a/drivers/net/wireless/intel/iwlwifi/mld/power.c b/drivers/net/wireless/intel/iwlwifi/mld/power.c index ed7c0319f239b..2f16c174b57e5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/power.c @@ -15,11 +15,12 @@ static void iwl_mld_vif_ps_iterator(void *data, u8 *mac, struct ieee80211_vif *vif) { bool *ps_enable = (bool *)data; + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); if (vif->type != NL80211_IFTYPE_STATION) return; - *ps_enable &= vif->cfg.ps; + *ps_enable &= !mld_vif->ps_disabled; } int iwl_mld_update_device_power(struct iwl_mld *mld, bool d3) |