summaryrefslogtreecommitdiff
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>2023-09-28 17:35:38 +0300
committerJohannes Berg <johannes.berg@intel.com>2023-10-23 11:45:17 +0200
commit3831f6d8ce9c3c237a561219a2fb9c41ec800331 (patch)
tree71a3b385fa9663264d2f202dcfdbc5e5e0125fa4 /net/mac80211/sta_info.c
parentc7d91ccb442538fb75a55ac55b44a00d5bef2841 (diff)
wifi: mac80211: purge TX queues in flush_queues flow
When this flow is invoked with the "drop" parameter as true, we only drop the frames from the hw queues, but not from the sw queues. So when we call wake_queues() after hw queue purging, all the frames from the sw queues will be TX'ed, when what we actually want to do is to purge all queues in order to not TX anything... This can cause, for example, TXing data frames to the peer after the deauth frame was sent. Fix this by purging the sw queues in addition to the hw queues if the drop parameter is true. Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20230928172905.8fc2ee23e56f.I8b3f6def9c28ea96261e2d31df8786986fb5385b@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index ba36fc29e532..450700173422 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -113,6 +113,23 @@ static int link_sta_info_hash_del(struct ieee80211_local *local,
&link_sta->link_hash_node, link_sta_rht_params);
}
+void ieee80211_purge_sta_txqs(struct sta_info *sta)
+{
+ struct ieee80211_local *local = sta->sdata->local;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
+ struct txq_info *txqi;
+
+ if (!sta->sta.txq[i])
+ continue;
+
+ txqi = to_txq_info(sta->sta.txq[i]);
+
+ ieee80211_txq_purge(local, txqi);
+ }
+}
+
static void __cleanup_single_sta(struct sta_info *sta)
{
int ac, i;
@@ -139,16 +156,7 @@ static void __cleanup_single_sta(struct sta_info *sta)
atomic_dec(&ps->num_sta_ps);
}
- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
- struct txq_info *txqi;
-
- if (!sta->sta.txq[i])
- continue;
-
- txqi = to_txq_info(sta->sta.txq[i]);
-
- ieee80211_txq_purge(local, txqi);
- }
+ ieee80211_purge_sta_txqs(sta);
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);