Commit d00800a2 authored by Johannes Berg's avatar Johannes Berg
Browse files

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
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3950,6 +3950,10 @@ struct ieee80211_prep_tx_info {
 *	Note that vif can be NULL.
 *	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
 *	switch operation for CSAs received from the AP may implement this
 *	callback. They must then call ieee80211_chswitch_done() to indicate
@@ -4415,6 +4419,8 @@ struct ieee80211_ops {
#endif
	void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		      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,
			       struct ieee80211_vif *vif,
			       struct ieee80211_channel_switch *ch_switch);
+15 −0
Original line number Diff line number Diff line
@@ -649,6 +649,21 @@ static inline void drv_flush(struct ieee80211_local *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,
				      struct ieee80211_sub_if_data *sdata,
				      struct ieee80211_channel_switch *ch_switch)
+6 −2
Original line number Diff line number Diff line
@@ -1299,8 +1299,12 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
	 * frames sitting on hardware queues might be sent out without
	 * any encryption at all.
	 */
	if (local->ops->set_key)
	if (local->ops->set_key) {
		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 */
	ieee80211_free_sta_keys(local, sta);
+7 −0
Original line number Diff line number Diff line
@@ -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,
	TP_PROTO(struct ieee80211_local *local,
		 struct ieee80211_sub_if_data *sdata,