mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 08:33:17 +02:00
wifi: iwlwifi: mvm: exit EMLSR upon missed beacon
In case of more than 6 missed beacons on one of the links, exit EMLSR by deactivating that link. Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://msgid.link/20240416134215.f9111c79cb53.Ie95ea60149a9bc4367f6b338b37c8635051351ba@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
0bcc215598
commit
48ac6c8ed7
|
|
@ -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
|
||||
|
|
@ -123,5 +123,6 @@
|
|||
#define IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT 3000 /* in seconds */
|
||||
#define IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT 60 /* in seconds */
|
||||
#define IWL_MVM_AUTO_EML_ENABLE true
|
||||
#define IWL_MVM_MISSED_BEACONS_EXIT_ESR_THRESH 7
|
||||
|
||||
#endif /* __MVM_CONSTANTS_H */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -692,6 +693,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,
|
||||
|
|
@ -720,8 +740,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)
|
||||
|
|
|
|||
|
|
@ -1591,23 +1591,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,
|
||||
|
|
@ -1620,7 +1620,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);
|
||||
|
||||
|
|
@ -1647,6 +1647,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);
|
||||
|
|
@ -1660,7 +1664,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);
|
||||
|
|
@ -1672,9 +1676,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,
|
||||
|
|
|
|||
|
|
@ -354,11 +354,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
|
||||
|
|
@ -1963,6 +1967,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(CONFIG_IWLWIFI_KUNIT_TESTS)
|
||||
unsigned int iwl_mvm_get_link_grade(struct ieee80211_bss_conf *link_conf);
|
||||
|
|
|
|||
|
|
@ -372,7 +372,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),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user