From: Johannes Berg <johannes.berg@xxxxxxxxx> For iwlwifi this is simple to implement, and on newer hardware it's an improvement since we have per-station queues. Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx> Signed-off-by: Gregory Greenman <gregory.greenman@xxxxxxxxx> --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 25 +++++++++++++++++++ .../wireless/intel/iwlwifi/mvm/mld-mac80211.c | 1 + drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 ++ 3 files changed, 28 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index ebe4163837a0..f083ebda1e83 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -5652,6 +5652,30 @@ void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, iwl_trans_wait_tx_queues_empty(mvm->trans, msk); } +void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + int i; + + mutex_lock(&mvm->mutex); + for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { + struct iwl_mvm_sta *mvmsta; + struct ieee80211_sta *tmp; + + tmp = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], + lockdep_is_held(&mvm->mutex)); + if (tmp != sta) + continue; + + mvmsta = iwl_mvm_sta_from_mac80211(sta); + + if (iwl_mvm_flush_sta(mvm, mvmsta, false)) + IWL_ERR(mvm, "flush request fail\n"); + } + mutex_unlock(&mvm->mutex); +} + int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) { @@ -6204,6 +6228,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx, .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover, .flush = iwl_mvm_mac_flush, + .flush_sta = iwl_mvm_mac_flush_sta, .sched_scan_start = iwl_mvm_mac_sched_scan_start, .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, .set_key = iwl_mvm_mac_set_key, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index 636ad2b76428..8b6c641772ee 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -1149,6 +1149,7 @@ const struct ieee80211_ops iwl_mvm_mld_hw_ops = { .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx, .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover, .flush = iwl_mvm_mac_flush, + .flush_sta = iwl_mvm_mac_flush_sta, .sched_scan_start = iwl_mvm_mac_sched_scan_start, .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, .set_key = iwl_mvm_mac_set_key, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index b575ce2f7146..b83df0631279 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2659,6 +2659,8 @@ void iwl_mvm_mac_mgd_complete_tx(struct ieee80211_hw *hw, struct ieee80211_prep_tx_info *info); void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop); +void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *req, -- 2.38.1