Commit d00800a2 authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: add flush_sta method

Some drivers like iwlwifi might have per-STA queues, so we
may want to flush/drop just those queues rather than all
when removing a station. Add a separate method for that.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 0b75a1b1
...@@ -3950,6 +3950,10 @@ struct ieee80211_prep_tx_info { ...@@ -3950,6 +3950,10 @@ struct ieee80211_prep_tx_info {
* Note that vif can be NULL. * Note that vif can be NULL.
* The callback can sleep. * The callback can sleep.
* *
* @flush_sta: Flush or drop all pending frames from the hardware queue(s) for
* the given station, as it's about to be removed.
* The callback can sleep.
*
* @channel_switch: Drivers that need (or want) to offload the channel * @channel_switch: Drivers that need (or want) to offload the channel
* switch operation for CSAs received from the AP may implement this * switch operation for CSAs received from the AP may implement this
* callback. They must then call ieee80211_chswitch_done() to indicate * callback. They must then call ieee80211_chswitch_done() to indicate
...@@ -4415,6 +4419,8 @@ struct ieee80211_ops { ...@@ -4415,6 +4419,8 @@ struct ieee80211_ops {
#endif #endif
void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop); u32 queues, bool drop);
void (*flush_sta)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
void (*channel_switch)(struct ieee80211_hw *hw, void (*channel_switch)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_channel_switch *ch_switch); struct ieee80211_channel_switch *ch_switch);
......
...@@ -649,6 +649,21 @@ static inline void drv_flush(struct ieee80211_local *local, ...@@ -649,6 +649,21 @@ static inline void drv_flush(struct ieee80211_local *local,
trace_drv_return_void(local); trace_drv_return_void(local);
} }
static inline void drv_flush_sta(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct sta_info *sta)
{
might_sleep();
if (sdata && !check_sdata_in_driver(sdata))
return;
trace_drv_flush_sta(local, sdata, &sta->sta);
if (local->ops->flush_sta)
local->ops->flush_sta(&local->hw, &sdata->vif, &sta->sta);
trace_drv_return_void(local);
}
static inline void drv_channel_switch(struct ieee80211_local *local, static inline void drv_channel_switch(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel_switch *ch_switch) struct ieee80211_channel_switch *ch_switch)
......
...@@ -1299,8 +1299,12 @@ static void __sta_info_destroy_part2(struct sta_info *sta) ...@@ -1299,8 +1299,12 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
* frames sitting on hardware queues might be sent out without * frames sitting on hardware queues might be sent out without
* any encryption at all. * any encryption at all.
*/ */
if (local->ops->set_key) if (local->ops->set_key) {
ieee80211_flush_queues(local, sta->sdata, false); if (local->ops->flush_sta)
drv_flush_sta(local, sta->sdata, sta);
else
ieee80211_flush_queues(local, sta->sdata, false);
}
/* now keys can no longer be reached */ /* now keys can no longer be reached */
ieee80211_free_sta_keys(local, sta); ieee80211_free_sta_keys(local, sta);
......
...@@ -1177,6 +1177,13 @@ TRACE_EVENT(drv_flush, ...@@ -1177,6 +1177,13 @@ TRACE_EVENT(drv_flush,
) )
); );
DEFINE_EVENT(sta_event, drv_flush_sta,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct ieee80211_sta *sta),
TP_ARGS(local, sdata, sta)
);
TRACE_EVENT(drv_channel_switch, TRACE_EVENT(drv_channel_switch,
TP_PROTO(struct ieee80211_local *local, TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, struct ieee80211_sub_if_data *sdata,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment