aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>2024-12-24 19:27:30 +0200
committerJohannes Berg <johannes.berg@intel.com>2025-01-13 13:53:04 +0100
commit687a7c8a722743526b4fe45fc75c6999990480ab (patch)
tree20b18d61e4d0e721d5117c6e09e637c1634bef13 /net/mac80211
parentwifi: mac80211: add an option to filter a sta from being flushed (diff)
downloadlinux-rng-687a7c8a722743526b4fe45fc75c6999990480ab.tar.xz
linux-rng-687a7c8a722743526b4fe45fc75c6999990480ab.zip
wifi: mac80211: change disassoc sequence a bit
Currently, the sequence goes like this (among others): 1. flush all stations (including the AP ones) -> this will tell the drivers to remove the stations 2. notify the driver the vif is not associated. Which means that in between 1 and 2, the state is that the vif is associated, but there is no AP station, which makes no sense, and may be problematic for some drivers (for example iwlwifi) Change the sequence to: 1. flush the TDLS stations 2. move the AP station to IEEE80211_STA_NONE 3. notify the driver about the vif being unassociated 4. flush the AP station In order to not break other drivers, add a vif flag to indicate whether the driver wants to new sequence or not. If the flag is not set, then things will be done in the old sequence. Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Link: https://patch.msgid.link/20241224192322.996ad1be6cb3.I7815d33415aa1d65c0120b54be7a15a45388f807@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mlme.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 61c318f5239f..e502f6d57289 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3599,6 +3599,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
+ struct sta_info *ap_sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
unsigned int link_id;
u64 changed = 0;
struct ieee80211_prep_tx_info info = {
@@ -3609,6 +3610,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
lockdep_assert_wiphy(local->hw.wiphy);
+ if (WARN_ON(!ap_sta))
+ return;
+
if (WARN_ON_ONCE(tx && !frame_buf))
return;
@@ -3672,8 +3676,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
sdata->vif.cfg.ssid_len = 0;
- /* remove AP and TDLS peers */
- sta_info_flush(sdata, -1);
+ /* Remove TDLS peers */
+ __sta_info_flush(sdata, false, -1, ap_sta);
+
+ if (sdata->vif.driver_flags & IEEE80211_VIF_REMOVE_AP_AFTER_DISASSOC) {
+ /* Only move the AP state */
+ sta_info_move_state(ap_sta, IEEE80211_STA_NONE);
+ } else {
+ /* Remove AP peer */
+ sta_info_flush(sdata, -1);
+ }
/* finally reset all BSS / config parameters */
if (!ieee80211_vif_is_mld(&sdata->vif))
@@ -3724,6 +3736,14 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
ieee80211_vif_cfg_change_notify(sdata, changed);
}
+ if (sdata->vif.driver_flags & IEEE80211_VIF_REMOVE_AP_AFTER_DISASSOC) {
+ /*
+ * After notifying the driver about the disassoc,
+ * remove the ap sta.
+ */
+ sta_info_flush(sdata, -1);
+ }
+
/* disassociated - set to defaults now */
ieee80211_set_wmm_default(&sdata->deflink, false, false);