forked from mirrors/linux
		
	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: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									0b75a1b1e4
								
							
						
					
					
						commit
						d00800a289
					
				
					 4 changed files with 34 additions and 2 deletions
				
			
		| 
						 | 
					@ -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 {
 | 
				
			||||||
#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,
 | 
				
			||||||
	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)
 | 
				
			||||||
	 * 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,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue