mirror of https://gitee.com/openkylin/linux.git
iwlwifi: mvm: don't send BAR on flushed frames
When we flush a queue, the packets will have a 'failed' status but we shouldn't send a BAR. This check was missing. Because of that, when we got an ampdu_action with IEEE80211_AMPDU_TX_STOP_FLUSH, we started the following ping pong with the firmware: 1) Set the station as 'draining' 2) Get a failed Tx status (DRAINED) 3) Send a BAR because of the failed Tx status (loop of 2 and 3) This loop wasn't endless since the BAR isn't sent on a queue that would trigger a "nested" BAR. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
3edfb5f44b
commit
114db230d3
|
@ -1331,6 +1331,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||||
while (!skb_queue_empty(&skbs)) {
|
while (!skb_queue_empty(&skbs)) {
|
||||||
struct sk_buff *skb = __skb_dequeue(&skbs);
|
struct sk_buff *skb = __skb_dequeue(&skbs);
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
|
bool flushed = false;
|
||||||
|
|
||||||
skb_freed++;
|
skb_freed++;
|
||||||
|
|
||||||
|
@ -1344,6 +1345,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||||
case TX_STATUS_DIRECT_DONE:
|
case TX_STATUS_DIRECT_DONE:
|
||||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||||
break;
|
break;
|
||||||
|
case TX_STATUS_FAIL_FIFO_FLUSHED:
|
||||||
|
case TX_STATUS_FAIL_DRAIN_FLOW:
|
||||||
|
flushed = true;
|
||||||
|
break;
|
||||||
case TX_STATUS_FAIL_DEST_PS:
|
case TX_STATUS_FAIL_DEST_PS:
|
||||||
/* the FW should have stopped the queue and not
|
/* the FW should have stopped the queue and not
|
||||||
* return this status
|
* return this status
|
||||||
|
@ -1366,7 +1371,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||||
/* Single frame failure in an AMPDU queue => send BAR */
|
/* Single frame failure in an AMPDU queue => send BAR */
|
||||||
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
|
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
|
||||||
!(info->flags & IEEE80211_TX_STAT_ACK) &&
|
!(info->flags & IEEE80211_TX_STAT_ACK) &&
|
||||||
!(info->flags & IEEE80211_TX_STAT_TX_FILTERED))
|
!(info->flags & IEEE80211_TX_STAT_TX_FILTERED) && !flushed)
|
||||||
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
||||||
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
|
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue