link.c (eead3591096e1cf5ab7f8ee9313b13e7727a4044) link.c (a1efeb823084020c31412cc8f2b5d110ad3e58a3)
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/*
3 * Copyright (C) 2022 - 2024 Intel Corporation
4 */
5#include "mvm.h"
6#include "time-event.h"
7
8static u32 iwl_mvm_get_free_fw_link_id(struct iwl_mvm *mvm,

--- 94 unchanged lines hidden (view full) ---

103 memcpy(cmd.ibss_bssid_addr, link_conf->bssid, ETH_ALEN);
104
105 if (cmd_ver < 2)
106 cmd.listen_lmac = cpu_to_le32(link_info->listen_lmac);
107
108 return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_ADD);
109}
110
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/*
3 * Copyright (C) 2022 - 2024 Intel Corporation
4 */
5#include "mvm.h"
6#include "time-event.h"
7
8static u32 iwl_mvm_get_free_fw_link_id(struct iwl_mvm *mvm,

--- 94 unchanged lines hidden (view full) ---

103 memcpy(cmd.ibss_bssid_addr, link_conf->bssid, ETH_ALEN);
104
105 if (cmd_ver < 2)
106 cmd.listen_lmac = cpu_to_le32(link_info->listen_lmac);
107
108 return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_ADD);
109}
110
111struct iwl_mvm_esr_iter_data {
112 struct ieee80211_vif *vif;
113 unsigned int link_id;
114 bool lift_block;
115};
116
117static void iwl_mvm_esr_vif_iterator(void *_data, u8 *mac,
118 struct ieee80211_vif *vif)
119{
120 struct iwl_mvm_esr_iter_data *data = _data;
121 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
122 int link_id;
123
124 if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_STATION)
125 return;
126
127 for_each_mvm_vif_valid_link(mvmvif, link_id) {
128 struct iwl_mvm_vif_link_info *link_info =
129 mvmvif->link[link_id];
130 if (vif == data->vif && link_id == data->link_id)
131 continue;
132 if (link_info->active)
133 data->lift_block = false;
134 }
135}
136
137int iwl_mvm_esr_non_bss_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
138 unsigned int link_id, bool active)
139{
140 /* An active link of a non-station vif blocks EMLSR. Upon activation
141 * block EMLSR on the bss vif. Upon deactivation, check if this link
142 * was the last non-station link active, and if so unblock the bss vif
143 */
144 struct ieee80211_vif *bss_vif = iwl_mvm_get_bss_vif(mvm);
145 struct iwl_mvm_esr_iter_data data = {
146 .vif = vif,
147 .link_id = link_id,
148 .lift_block = true,
149 };
150
151 if (IS_ERR_OR_NULL(bss_vif))
152 return 0;
153
154 if (active)
155 return iwl_mvm_block_esr_sync(mvm, bss_vif,
156 IWL_MVM_ESR_BLOCKED_NON_BSS);
157
158 ieee80211_iterate_active_interfaces(mvm->hw,
159 IEEE80211_IFACE_ITER_NORMAL,
160 iwl_mvm_esr_vif_iterator, &data);
161 if (data.lift_block) {
162 mutex_lock(&mvm->mutex);
163 iwl_mvm_unblock_esr(mvm, bss_vif, IWL_MVM_ESR_BLOCKED_NON_BSS);
164 mutex_unlock(&mvm->mutex);
165 }
166
167 return 0;
168}
169
111int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
112 struct ieee80211_bss_conf *link_conf,
113 u32 changes, bool active)
114{
115 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
116 unsigned int link_id = link_conf->link_id;
117 struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id];
118 struct iwl_mvm_phy_ctxt *phyctxt;

--- 800 unchanged lines hidden (view full) ---

919 IWL_DEBUG_INFO(mvm, "Blocking EMLSR mode. reason = 0x%x\n",
920 reason);
921
922 mvmvif->esr_disable_reason |= reason;
923
924 iwl_mvm_exit_esr(mvm, vif, reason, link_to_keep);
925}
926
170int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
171 struct ieee80211_bss_conf *link_conf,
172 u32 changes, bool active)
173{
174 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
175 unsigned int link_id = link_conf->link_id;
176 struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id];
177 struct iwl_mvm_phy_ctxt *phyctxt;

--- 800 unchanged lines hidden (view full) ---

978 IWL_DEBUG_INFO(mvm, "Blocking EMLSR mode. reason = 0x%x\n",
979 reason);
980
981 mvmvif->esr_disable_reason |= reason;
982
983 iwl_mvm_exit_esr(mvm, vif, reason, link_to_keep);
984}
985
986int iwl_mvm_block_esr_sync(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
987 enum iwl_mvm_esr_state reason)
988{
989 int primary_link = iwl_mvm_get_primary_link(vif);
990 int ret;
991
992 if (!IWL_MVM_AUTO_EML_ENABLE || !ieee80211_vif_is_mld(vif))
993 return 0;
994
995 /* This should be called only with blocking reasons */
996 if (WARN_ON(!(reason & IWL_MVM_BLOCK_ESR_REASONS)))
997 return 0;
998
999 /* leave ESR immediately, not only async with iwl_mvm_block_esr() */
1000 ret = ieee80211_set_active_links(vif, BIT(primary_link));
1001 if (ret)
1002 return ret;
1003
1004 mutex_lock(&mvm->mutex);
1005 /* only additionally block for consistency and to avoid concurrency */
1006 iwl_mvm_block_esr(mvm, vif, reason, primary_link);
1007 mutex_unlock(&mvm->mutex);
1008
1009 return 0;
1010}
1011
927static void iwl_mvm_esr_unblocked(struct iwl_mvm *mvm,
928 struct ieee80211_vif *vif)
929{
930 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
931 bool need_new_sel = time_after(jiffies, mvmvif->last_esr_exit.ts +
932 IWL_MVM_TRIGGER_LINK_SEL_TIME);
933
934 lockdep_assert_held(&mvm->mutex);

--- 51 unchanged lines hidden ---
1012static void iwl_mvm_esr_unblocked(struct iwl_mvm *mvm,
1013 struct ieee80211_vif *vif)
1014{
1015 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1016 bool need_new_sel = time_after(jiffies, mvmvif->last_esr_exit.ts +
1017 IWL_MVM_TRIGGER_LINK_SEL_TIME);
1018
1019 lockdep_assert_held(&mvm->mutex);

--- 51 unchanged lines hidden ---