mac80211: agg-tx: add an option to defer ADDBA transmit
authorMordechay Goodstein <mordechay.goodstein@intel.com>
Thu, 26 Mar 2020 13:09:38 +0000 (15:09 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 24 Apr 2020 10:33:43 +0000 (12:33 +0200)
Driver tells mac80211 to sends ADDBA with SSN (starting sequence number)
from the head of the queue, while the transmission of all the frames in the
queue may take a while, which causes the peer to time out. In order to
fix this scenario, add an option to defer ADDBA transmit until queue
is drained.

Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20200326150855.0f27423fec75.If67daab123a27c1cbddef000d6a3f212aa6309ef@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/agg-tx.c
net/mac80211/sta_info.h

index 5fb80dd..f314763 100644 (file)
@@ -3125,7 +3125,10 @@ enum ieee80211_filter_flags {
  * @IEEE80211_AMPDU_RX_START: start RX aggregation
  * @IEEE80211_AMPDU_RX_STOP: stop RX aggregation
  * @IEEE80211_AMPDU_TX_START: start TX aggregation, the driver must either
- *     call ieee80211_start_tx_ba_cb_irqsafe() or return the special
+ *     call ieee80211_start_tx_ba_cb_irqsafe() or
+ *     call ieee80211_start_tx_ba_cb_irqsafe() with status
+ *     %IEEE80211_AMPDU_TX_START_DELAY_ADDBA to delay addba after
+ *     ieee80211_start_tx_ba_cb_irqsafe is called, or just return the special
  *     status %IEEE80211_AMPDU_TX_START_IMMEDIATE.
  * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational
  * @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting
@@ -3151,6 +3154,7 @@ enum ieee80211_ampdu_mlme_action {
 };
 
 #define IEEE80211_AMPDU_TX_START_IMMEDIATE 1
+#define IEEE80211_AMPDU_TX_START_DELAY_ADDBA 2
 
 /**
  * struct ieee80211_ampdu_params - AMPDU action parameters
index 32f40c4..c2d5f51 100644 (file)
@@ -483,6 +483,8 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
                                     tid_tx->dialog_token,
                                     sta->tid_seq[tid] >> 4,
                                     buf_size, tid_tx->timeout);
+
+       WARN_ON(test_and_set_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state));
 }
 
 void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
@@ -521,7 +523,9 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
 
        params.ssn = sta->tid_seq[tid] >> 4;
        ret = drv_ampdu_action(local, sdata, &params);
-       if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) {
+       if (ret == IEEE80211_AMPDU_TX_START_DELAY_ADDBA) {
+               return;
+       } else if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) {
                /*
                 * We didn't send the request yet, so don't need to check
                 * here if we already got a response, just mark as driver
@@ -765,6 +769,12 @@ void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid,
        if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)))
                return;
 
+       if (!test_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)) {
+               ieee80211_send_addba_with_timeout(sta, tid_tx);
+               /* RESPONSE_RECEIVED state whould trigger the flow again */
+               return;
+       }
+
        if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state))
                ieee80211_agg_tx_operational(local, sta, tid);
 }
index 36f1aba..a5de3aa 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright 2002-2005, Devicescape Software, Inc.
  * Copyright 2013-2014  Intel Mobile Communications GmbH
  * Copyright(c) 2015-2017 Intel Deutschland GmbH
+ * Copyright(c) 2020 Intel Corporation
  */
 
 #ifndef STA_INFO_H
@@ -116,6 +117,7 @@ enum ieee80211_sta_info_flags {
 #define HT_AGG_STATE_WANT_STOP         5
 #define HT_AGG_STATE_START_CB          6
 #define HT_AGG_STATE_STOP_CB           7
+#define HT_AGG_STATE_SENT_ADDBA                8
 
 DECLARE_EWMA(avg_signal, 10, 8)
 enum ieee80211_agg_stop_reason {