diff options
author | Miri Korenblit <miriam.rachel.korenblit@intel.com> | 2024-02-15 18:16:50 +0200 |
---|---|---|
committer | iwlwifi publisher <> | 2024-04-17 12:59:50 +0000 |
commit | a8d789444663000b00826575df8ca7df8335cbbe (patch) | |
tree | c0d2e1517b45546c82e854d3aeb0f6c43b22fe9f | |
parent | c28e93a683496d912e6727fdbdfa043edc5f8081 (diff) | |
download | backport-iwlwifi-a8d789444663000b00826575df8ca7df8335cbbe.tar.gz |
wifi: iwlwifi: mvm: exit EMLSR upon missed beacon
In case of more than 6 missed beacons on one of the links,
exit esr by deactivating that link.
type=feature
ticket=jira:WIFI-388590
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Change-Id: Ie95ea60149a9bc4367f6b338b37c8635051351ba
Reviewed-on: https://gerritwcs.ir.intel.com/c/iwlwifi-stack-dev/+/94796
tested: iil_jenkins iil_jenkins <EC.GER.UNIX.IIL.JENKINS@INTEL.COM>
x-iwlwifi-stack-dev: df9aeee2312cd3151e96227504cdcb76b6a18d15
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-dbg-cfg.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/link.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 | ||||
-rw-r--r-- | versions | 2 |
7 files changed, 43 insertions, 15 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-cfg.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-cfg.h index af8b6c67df..1832929b1c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-cfg.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-cfg.h @@ -191,6 +191,7 @@ struct iwl_dbg_cfg { IWL_DBG_CFG_RANGE(u8, MVM_ADAPTIVE_DWELL_NUM_APS_OVERRIDE, 0, 10) IWL_DBG_CFG_DEF(int, eml_capa_override, -1) IWL_DBG_CFG(bool, MVM_AUTO_EML_ENABLE) + IWL_DBG_CFG(u8, MVM_MISSED_BEACONS_EXIT_ESR_THRESH) #endif /* CPTCFG_IWLMVM */ #ifdef CPTCFG_IWLWIFI_DEVICE_TESTMODE IWL_DBG_CFG_NODEF(u32, dnt_out_mode) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h index 44922838d5..37324a9138 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2013-2015 Intel Mobile Communications GmbH - * Copyright (C) 2013-2014, 2018-2023 Intel Corporation + * Copyright (C) 2013-2014, 2018-2024 Intel Corporation * Copyright (C) 2015 Intel Deutschland GmbH */ #ifndef __MVM_CONSTANTS_H @@ -127,6 +127,7 @@ #define IWL_MVM_MIN_BEACON_INTERVAL_TU 16 #define IWL_MVM_ADAPTIVE_DWELL_NUM_APS_OVERRIDE 0 #define IWL_MVM_AUTO_EML_ENABLE true +#define IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH 7 #else /* CPTCFG_IWLWIFI_SUPPORT_DEBUG_OVERRIDES */ #define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (mvm->trans->dbg_cfg.MVM_DEFAULT_PS_TX_DATA_TIMEOUT) #define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (mvm->trans->dbg_cfg.MVM_DEFAULT_PS_RX_DATA_TIMEOUT) @@ -245,6 +246,7 @@ #define IWL_MVM_MIN_BEACON_INTERVAL_TU (mvm->trans->dbg_cfg.MVM_MIN_BEACON_INTERVAL_TU) #define IWL_MVM_ADAPTIVE_DWELL_NUM_APS_OVERRIDE (mvm->trans->dbg_cfg.MVM_ADAPTIVE_DWELL_NUM_APS_OVERRIDE) #define IWL_MVM_AUTO_EML_ENABLE (mvm->trans->dbg_cfg.MVM_AUTO_EML_ENABLE) +#define IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH (mvm->trans->dbg_cfg.MVM_MISSED_BEACONS_EXIT_ESR_THRESH) #endif /* CPTCFG_IWLWIFI_SUPPORT_DEBUG_OVERRIDES */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index bff0a6decf..4983fc3441 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -527,6 +527,7 @@ u8 iwl_mvm_set_link_selection_data(struct ieee80211_vif *vif, u16 max_grade = 0; unsigned long link_id; + /* TODO: don't select links that weren't discovered in the last scan */ for_each_set_bit(link_id, &usable_links, IEEE80211_MLD_MAX_NUM_LINKS) { struct ieee80211_bss_conf *link_conf = link_conf_dereference_protected(vif, link_id); @@ -690,6 +691,25 @@ u8 iwl_mvm_get_primary_link(struct ieee80211_vif *vif) return __ffs(vif->active_links); } +/* + * For non-MLO/single link, this will return the deflink/single active link, + * respectively + */ +u8 iwl_mvm_get_other_link(struct ieee80211_vif *vif, u8 link_id) +{ + switch (hweight16(vif->active_links)) { + case 0: + return 0; + default: + WARN_ON(1); + fallthrough; + case 1: + return __ffs(vif->active_links); + case 2: + return __ffs(vif->active_links & ~BIT(link_id)); + } +} + /* API to exit eSR mode */ void iwl_mvm_exit_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif, enum iwl_mvm_esr_state reason, @@ -718,8 +738,6 @@ void iwl_mvm_exit_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ieee80211_set_active_links_async(vif, new_active_links); } -#define IWL_MVM_BLOCK_ESR_REASONS IWL_MVM_ESR_BLOCKED_COEX - void iwl_mvm_block_esr(struct iwl_mvm *mvm, struct ieee80211_vif *vif, enum iwl_mvm_esr_state reason, u8 link_to_keep) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 442875d06c..06ec2c578d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1618,23 +1618,23 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, u32 id = le32_to_cpu(mb->link_id); union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt }; u32 mac_type; + int link_id = -1; u8 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, MISSED_BEACONS_NOTIFICATION, 0); - rcu_read_lock(); - /* before version four the ID in the notification refers to mac ID */ if (notif_ver < 4) { - vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, true); + vif = iwl_mvm_rcu_dereference_vif_id(mvm, id, false); } else { struct ieee80211_bss_conf *bss_conf = - iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, true); + iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, id, false); if (!bss_conf) - goto out; + return; vif = bss_conf->vif; + link_id = bss_conf->link_id; } IWL_DEBUG_INFO(mvm, @@ -1647,7 +1647,7 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, le32_to_cpu(mb->num_expected_beacons)); if (!vif) - goto out; + return; mac_type = iwl_mvm_get_mac_type(vif); @@ -1674,6 +1674,10 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, "missed_beacons:%d, missed_beacons_since_rx:%d\n", rx_missed_bcon, rx_missed_bcon_since_rx); } + } else if (rx_missed_bcon >= IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH && + link_id >= 0 && hweight16(vif->active_links) > 1) { + iwl_mvm_exit_esr(mvm, vif, IWL_MVM_ESR_EXIT_MISSED_BEACON, + iwl_mvm_get_other_link(vif, link_id)); } else if (rx_missed_bcon_since_rx > IWL_MVM_MISSED_BEACONS_THRESHOLD) { if (!iwl_mvm_has_new_tx_api(mvm)) ieee80211_beacon_loss(vif); @@ -1687,7 +1691,7 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, trigger = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif), FW_DBG_TRIGGER_MISSED_BEACONS); if (!trigger) - goto out; + return; bcon_trig = (void *)trigger->data; stop_trig_missed_bcon = le32_to_cpu(bcon_trig->stop_consec_missed_bcon); @@ -1699,9 +1703,6 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx || rx_missed_bcon >= stop_trig_missed_bcon) iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL); - -out: - rcu_read_unlock(); } void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 61d532076f..dff022f78d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -356,11 +356,15 @@ struct iwl_mvm_vif_link_info { * reasons - use iwl_mvm_exit_esr(). * * @IWL_MVM_ESR_BLOCKED_COEX: COEX is preventing the enablement of EMLSR + * @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons */ enum iwl_mvm_esr_state { IWL_MVM_ESR_BLOCKED_COEX = 0x1, + IWL_MVM_ESR_EXIT_MISSED_BEACON = 0x10000, }; +#define IWL_MVM_BLOCK_ESR_REASONS 0xffff + /** * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context * @mvm: pointer back to the mvm struct @@ -2002,6 +2006,7 @@ int iwl_mvm_disable_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, void iwl_mvm_select_links(struct iwl_mvm *mvm, struct ieee80211_vif *vif); u8 iwl_mvm_get_primary_link(struct ieee80211_vif *vif); +u8 iwl_mvm_get_other_link(struct ieee80211_vif *vif, u8 link_id); #if IS_ENABLED(CPTCFG_IWLWIFI_KUNIT_TESTS) unsigned int iwl_mvm_get_link_grade(struct ieee80211_bss_conf *link_conf); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index d370f1f3d0..dfa1c483ac 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -403,7 +403,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { struct iwl_umac_scan_iter_complete_notif), RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif, - RX_HANDLER_SYNC, struct iwl_missed_beacons_notif), + RX_HANDLER_ASYNC_LOCKED_WIPHY, + struct iwl_missed_beacons_notif), RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, RX_HANDLER_SYNC, struct iwl_error_resp), @@ -2,4 +2,4 @@ BACKPORTS_VERSION="(see git)" BACKPORTED_KERNEL_VERSION="(see git)" BACKPORTED_KERNEL_NAME="iwlwifi" BACKPORTS_BUILD_TSTAMP=__DATE__ \" \" __TIME__ -BACKPORTS_GIT_TRACKED="iwlwifi-stack-public:master:11948:2c9b64ad" +BACKPORTS_GIT_TRACKED="iwlwifi-stack-public:master:11949:df9aeee2" |