From 0c197f16f7bc5ddb43073690a80fb15998ad61e4 Mon Sep 17 00:00:00 2001
From: Mordechay Goodstein <mordechay.goodstein@intel.com>
Date: Thu, 26 Mar 2020 15:09:38 +0200
Subject: [PATCH] mac80211: agg-tx: add an option to defer ADDBA transmit
Git-commit: 0c197f16f7bc5ddb43073690a80fb15998ad61e4
Patch-mainline: v5.8-rc1
References: jsc#SLE-13430
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>
Acked-by: Takashi Iwai <tiwai@suse.de>
---
include/net/mac80211.h | 6 +++++-
net/mac80211/agg-tx.c | 12 +++++++++++-
net/mac80211/sta_info.h | 2 ++
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5fb80dd8bbbc..f3147633dda2 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -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
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 32f40c4f3120..c2d5f512526d 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -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, ¶ms);
- 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);
}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 36f1abaab9ff..a5de3aa6ea42 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -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 {
--
2.16.4