300a2b65c6eeea4817049798591edfcd09b01037
[openwrt/staging/dedeckeh.git] / package / kernel / mac80211 / patches / subsys / 333-wifi-mac80211-add-flush_sta-method.patch
1 From: Johannes Berg <johannes.berg@intel.com>
2 Date: Mon, 13 Mar 2023 11:53:51 +0100
3 Subject: [PATCH] wifi: mac80211: add flush_sta method
4
5 Some drivers like iwlwifi might have per-STA queues, so we
6 may want to flush/drop just those queues rather than all
7 when removing a station. Add a separate method for that.
8
9 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
10 Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com>
11 ---
12
13 --- a/include/net/mac80211.h
14 +++ b/include/net/mac80211.h
15 @@ -3922,6 +3922,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 @@ -4376,6 +4380,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 @@ -617,6 +617,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 @@ -1276,8 +1276,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 @@ -1177,6 +1177,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,