blob: ae2ef8352eb5ae2bfd1655b47b1f16286ed87f07 [file] [log] [blame]
developera1432902023-04-01 04:45:58 +08001From: Johannes Berg <johannes.berg@intel.com>
2Date: Mon, 13 Mar 2023 11:53:51 +0100
3Subject: [PATCH] wifi: mac80211: add flush_sta method
4
5Some drivers like iwlwifi might have per-STA queues, so we
6may want to flush/drop just those queues rather than all
7when removing a station. Add a separate method for that.
8
9Signed-off-by: Johannes Berg <johannes.berg@intel.com>
10Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
11---
12
13--- a/include/net/mac80211.h
14+++ b/include/net/mac80211.h
15@@ -3688,6 +3688,10 @@ struct ieee80211_prep_tx_info {
16 * Note that vif can be NULL.
17 * The callback can sleep.
18 *
19+ * @flush_sta: Flush or drop all pending frames from the hardware queue(s) for
20+ * the given station, as it's about to be removed.
21+ * The callback can sleep.
22+ *
23 * @channel_switch: Drivers that need (or want) to offload the channel
24 * switch operation for CSAs received from the AP may implement this
25 * callback. They must then call ieee80211_chswitch_done() to indicate
26@@ -4116,6 +4120,8 @@ struct ieee80211_ops {
27 #endif
28 void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
29 u32 queues, bool drop);
30+ void (*flush_sta)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
31+ struct ieee80211_sta *sta);
32 void (*channel_switch)(struct ieee80211_hw *hw,
33 struct ieee80211_vif *vif,
34 struct ieee80211_channel_switch *ch_switch);
35--- a/net/mac80211/driver-ops.h
36+++ b/net/mac80211/driver-ops.h
37@@ -639,6 +639,21 @@ static inline void drv_flush(struct ieee
38 trace_drv_return_void(local);
39 }
40
41+static inline void drv_flush_sta(struct ieee80211_local *local,
42+ struct ieee80211_sub_if_data *sdata,
43+ struct sta_info *sta)
44+{
45+ might_sleep();
46+
47+ if (sdata && !check_sdata_in_driver(sdata))
48+ return;
49+
50+ trace_drv_flush_sta(local, sdata, &sta->sta);
51+ if (local->ops->flush_sta)
52+ local->ops->flush_sta(&local->hw, &sdata->vif, &sta->sta);
53+ trace_drv_return_void(local);
54+}
55+
56 static inline void drv_channel_switch(struct ieee80211_local *local,
57 struct ieee80211_sub_if_data *sdata,
58 struct ieee80211_channel_switch *ch_switch)
59--- a/net/mac80211/sta_info.c
60+++ b/net/mac80211/sta_info.c
61@@ -1075,8 +1075,12 @@ static void __sta_info_destroy_part2(str
62 * frames sitting on hardware queues might be sent out without
63 * any encryption at all.
64 */
65- if (local->ops->set_key)
66- ieee80211_flush_queues(local, sta->sdata, false);
67+ if (local->ops->set_key) {
68+ if (local->ops->flush_sta)
69+ drv_flush_sta(local, sta->sdata, sta);
70+ else
71+ ieee80211_flush_queues(local, sta->sdata, false);
72+ }
73
74 /* now keys can no longer be reached */
75 ieee80211_free_sta_keys(local, sta);
76--- a/net/mac80211/trace.h
77+++ b/net/mac80211/trace.h
78@@ -1140,6 +1140,13 @@ TRACE_EVENT(drv_flush,
79 )
80 );
81
82+DEFINE_EVENT(sta_event, drv_flush_sta,
83+ TP_PROTO(struct ieee80211_local *local,
84+ struct ieee80211_sub_if_data *sdata,
85+ struct ieee80211_sta *sta),
86+ TP_ARGS(local, sdata, sta)
87+);
88+
89 TRACE_EVENT(drv_channel_switch,
90 TP_PROTO(struct ieee80211_local *local,
91 struct ieee80211_sub_if_data *sdata,