Commit 0c197f16 authored by Mordechay Goodstein's avatar Mordechay Goodstein Committed by Johannes Berg

mac80211: agg-tx: add an option to defer ADDBA transmit

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: default avatarMordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20200326150855.0f27423fec75.If67daab123a27c1cbddef000d6a3f212aa6309ef@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 31d8bb4e
...@@ -3125,7 +3125,10 @@ enum ieee80211_filter_flags { ...@@ -3125,7 +3125,10 @@ enum ieee80211_filter_flags {
* @IEEE80211_AMPDU_RX_START: start RX aggregation * @IEEE80211_AMPDU_RX_START: start RX aggregation
* @IEEE80211_AMPDU_RX_STOP: stop RX aggregation * @IEEE80211_AMPDU_RX_STOP: stop RX aggregation
* @IEEE80211_AMPDU_TX_START: start TX aggregation, the driver must either * @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. * status %IEEE80211_AMPDU_TX_START_IMMEDIATE.
* @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational
* @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting * @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting
...@@ -3151,6 +3154,7 @@ enum ieee80211_ampdu_mlme_action { ...@@ -3151,6 +3154,7 @@ enum ieee80211_ampdu_mlme_action {
}; };
#define IEEE80211_AMPDU_TX_START_IMMEDIATE 1 #define IEEE80211_AMPDU_TX_START_IMMEDIATE 1
#define IEEE80211_AMPDU_TX_START_DELAY_ADDBA 2
/** /**
* struct ieee80211_ampdu_params - AMPDU action parameters * struct ieee80211_ampdu_params - AMPDU action parameters
......
...@@ -483,6 +483,8 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta, ...@@ -483,6 +483,8 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
tid_tx->dialog_token, tid_tx->dialog_token,
sta->tid_seq[tid] >> 4, sta->tid_seq[tid] >> 4,
buf_size, tid_tx->timeout); 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) 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) ...@@ -521,7 +523,9 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
params.ssn = sta->tid_seq[tid] >> 4; params.ssn = sta->tid_seq[tid] >> 4;
ret = drv_ampdu_action(local, sdata, &params); 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 * We didn't send the request yet, so don't need to check
* here if we already got a response, just mark as driver * 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, ...@@ -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))) if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)))
return; 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)) if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state))
ieee80211_agg_tx_operational(local, sta, tid); ieee80211_agg_tx_operational(local, sta, tid);
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* Copyright 2002-2005, Devicescape Software, Inc. * Copyright 2002-2005, Devicescape Software, Inc.
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright(c) 2015-2017 Intel Deutschland GmbH * Copyright(c) 2015-2017 Intel Deutschland GmbH
* Copyright(c) 2020 Intel Corporation
*/ */
#ifndef STA_INFO_H #ifndef STA_INFO_H
...@@ -116,6 +117,7 @@ enum ieee80211_sta_info_flags { ...@@ -116,6 +117,7 @@ enum ieee80211_sta_info_flags {
#define HT_AGG_STATE_WANT_STOP 5 #define HT_AGG_STATE_WANT_STOP 5
#define HT_AGG_STATE_START_CB 6 #define HT_AGG_STATE_START_CB 6
#define HT_AGG_STATE_STOP_CB 7 #define HT_AGG_STATE_STOP_CB 7
#define HT_AGG_STATE_SENT_ADDBA 8
DECLARE_EWMA(avg_signal, 10, 8) DECLARE_EWMA(avg_signal, 10, 8)
enum ieee80211_agg_stop_reason { enum ieee80211_agg_stop_reason {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment