Skip to content

Commit e867062

Browse files
Miriam-Racheljmberg-intel
authored andcommitted
wifi: iwlwifi: mld: track channel_load_not_by_us
For each channel context, track the avarage channel load by others in the driver specific phy data, to be used by EMLSR. Due to FW limitations, this value is incorrect in EMLSR, so it is shouldn't be used in EMLSR. On EMLSR exit, clear it so the wrong value won't be used. Signed-off-by: Miri Korenblit <[email protected]> Reviewed-by: Emmanuel Grumbach <[email protected]> Link: https://patch.msgid.link/20250309073442.dd443fc5b178.I68b2fed197aae14888159b7a73bf40c2f346f41f@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent cb9716e commit e867062

File tree

5 files changed

+37
-1
lines changed

5 files changed

+37
-1
lines changed

drivers/net/wireless/intel/iwlwifi/mld/mac80211.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,7 @@ int iwl_mld_add_chanctx(struct ieee80211_hw *hw,
847847
if (fw_id < 0)
848848
return fw_id;
849849

850+
phy->mld = mld;
850851
phy->fw_id = fw_id;
851852
phy->chandef = *iwl_mld_get_chandef_from_chanctx(ctx);
852853

drivers/net/wireless/intel/iwlwifi/mld/mlo.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (C) 2024-2025 Intel Corporation
44
*/
55
#include "mlo.h"
6+
#include "phy.h"
67

78
/* Block reasons helper */
89
#define HANDLE_EMLSR_BLOCKED_REASONS(HOW) \
@@ -177,6 +178,19 @@ static void iwl_mld_check_emlsr_prevention(struct iwl_mld *mld,
177178
&mld_vif->emlsr.prevent_done_wk, delay);
178179
}
179180

181+
static void iwl_mld_clear_avg_chan_load_iter(struct ieee80211_hw *hw,
182+
struct ieee80211_chanctx_conf *ctx,
183+
void *dat)
184+
{
185+
struct iwl_mld_phy *phy = iwl_mld_phy_from_mac80211(ctx);
186+
187+
/* It is ok to do it for all chanctx (and not only for the ones that
188+
* belong to the EMLSR vif) since EMLSR is not allowed if there is
189+
* another vif.
190+
*/
191+
phy->avg_channel_load_not_by_us = 0;
192+
}
193+
180194
static int _iwl_mld_exit_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif,
181195
enum iwl_mld_emlsr_exit exit, u8 link_to_keep,
182196
bool sync)
@@ -215,6 +229,13 @@ static int _iwl_mld_exit_emlsr(struct iwl_mld *mld, struct ieee80211_vif *vif,
215229
/* Update latest exit reason and check EMLSR prevention */
216230
iwl_mld_check_emlsr_prevention(mld, mld_vif, exit);
217231

232+
/* channel_load_not_by_us is invalid when in EMLSR.
233+
* Clear it so wrong values won't be used.
234+
*/
235+
ieee80211_iter_chan_contexts_atomic(mld->hw,
236+
iwl_mld_clear_avg_chan_load_iter,
237+
NULL);
238+
218239
return ret;
219240
}
220241

drivers/net/wireless/intel/iwlwifi/mld/phy.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
* with. Used to detect a no-op when the chanctx changes.
1616
* @channel_load_by_us: channel load on this channel caused by
1717
* the NIC itself, as indicated by firmware
18+
* @avg_channel_load_not_by_us: averaged channel load on this channel caused by
19+
* others. This value is invalid when in EMLSR (due to FW limitations)
20+
* @mld: pointer to the MLD context
1821
*/
1922
struct iwl_mld_phy {
2023
/* Add here fields that need clean up on hw restart */
@@ -24,6 +27,8 @@ struct iwl_mld_phy {
2427
);
2528
/* And here fields that survive a hw restart */
2629
u32 channel_load_by_us;
30+
u32 avg_channel_load_not_by_us;
31+
struct iwl_mld *mld;
2732
};
2833

2934
static inline struct iwl_mld_phy *

drivers/net/wireless/intel/iwlwifi/mld/stats.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,14 +461,22 @@ static void iwl_mld_fill_chanctx_stats(struct ieee80211_hw *hw,
461461
{
462462
struct iwl_mld_phy *phy = iwl_mld_phy_from_mac80211(ctx);
463463
const struct iwl_stats_ntfy_per_phy *per_phy = data;
464+
u32 new_load;
464465

465466
if (WARN_ON(phy->fw_id >= IWL_STATS_MAX_PHY_OPERATIONAL))
466467
return;
467468

468469
phy->channel_load_by_us =
469470
le32_to_cpu(per_phy[phy->fw_id].channel_load_by_us);
470471

471-
/* TODO: channel load not by us (task=statistics) */
472+
new_load = le32_to_cpu(per_phy[phy->fw_id].channel_load_not_by_us);
473+
if (IWL_FW_CHECK(phy->mld, new_load > 100, "Invalid channel load %u\n",
474+
new_load))
475+
return;
476+
477+
/* give a weight of 0.5 for the old value */
478+
phy->avg_channel_load_not_by_us =
479+
(new_load >> 1) + (phy->avg_channel_load_not_by_us >> 1);
472480
}
473481

474482
static void

drivers/net/wireless/intel/iwlwifi/mld/tests/utils.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ iwlmld_kunit_add_chanctx_from_def(struct cfg80211_chan_def *def)
168168
KUNIT_ASSERT_GE(test, fw_id, 0);
169169

170170
phy->fw_id = fw_id;
171+
phy->mld = mld;
171172
phy->chandef = *iwl_mld_get_chandef_from_chanctx(ctx);
172173

173174
return ctx;

0 commit comments

Comments
 (0)