diff options
author | Andrei Otcheretianski <andrei.otcheretianski@intel.com> | 2018-07-24 21:57:50 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-12-17 22:37:37 +0300 |
commit | 1830e1a276bd6c5d4355293195037e4e814f9ce0 (patch) | |
tree | 0f33879eaf6ccaef348eafa915a8d1cf4f08e0af /drivers | |
parent | 9ae9efa0ae08a9f66ba82605e436d8bf316c796e (diff) | |
download | linux-1830e1a276bd6c5d4355293195037e4e814f9ce0.tar.xz |
iwlwifi: mvm: Send non offchannel traffic via AP sta
[ Upstream commit dc1aca22f8f38b7e2ad7b118db87404d11e68771 ]
TDLS discovery response frame is a unicast direct frame to the peer.
Since we don't have a STA for this peer, this frame goes through
iwl_tx_skb_non_sta(). As the result aux_sta and some completely
arbitrary queue would be selected for this frame, resulting in a queue
hang. Fix that by sending such frames through AP sta instead.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 77ed6ecf5ee5..b86c7a36d3f1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -822,6 +822,21 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) sta = NULL; + /* If there is no sta, and it's not offchannel - send through AP */ + if (info->control.vif->type == NL80211_IFTYPE_STATION && + info->hw_queue != IWL_MVM_OFFCHANNEL_QUEUE && !sta) { + struct iwl_mvm_vif *mvmvif = + iwl_mvm_vif_from_mac80211(info->control.vif); + u8 ap_sta_id = READ_ONCE(mvmvif->ap_sta_id); + + if (ap_sta_id < IWL_MVM_STATION_COUNT) { + /* mac80211 holds rcu read lock */ + sta = rcu_dereference(mvm->fw_id_to_mac_id[ap_sta_id]); + if (IS_ERR_OR_NULL(sta)) + goto drop; + } + } + if (sta) { if (iwl_mvm_defer_tx(mvm, sta, skb)) return; |