From ea08eeccae9297f7aabd2ef7f0c2517ac4549acc Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:18:26 +0000
Subject: [PATCH] write in 30M
---
kernel/net/mac80211/agg-tx.c | 160 ++++++++++++++++++++++++++++++++++-------------------
1 files changed, 102 insertions(+), 58 deletions(-)
diff --git a/kernel/net/mac80211/agg-tx.c b/kernel/net/mac80211/agg-tx.c
index 7913822..92e5812 100644
--- a/kernel/net/mac80211/agg-tx.c
+++ b/kernel/net/mac80211/agg-tx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* HT handling
*
@@ -8,11 +9,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2010, Intel Corporation
* Copyright(c) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2019 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright (C) 2018 - 2022 Intel Corporation
*/
#include <linux/ieee80211.h>
@@ -216,6 +213,8 @@
struct ieee80211_txq *txq = sta->sta.txq[tid];
struct txq_info *txqi;
+ lockdep_assert_held(&sta->ampdu_mlme.mtx);
+
if (!txq)
return;
@@ -229,7 +228,7 @@
clear_bit(IEEE80211_TXQ_STOP, &txqi->flags);
local_bh_disable();
rcu_read_lock();
- drv_wake_tx_queue(sta->sdata->local, txqi);
+ schedule_and_wake_txq(sta->sdata->local, txqi);
rcu_read_unlock();
local_bh_enable();
}
@@ -293,7 +292,6 @@
ieee80211_assign_tid_tx(sta, tid, NULL);
ieee80211_agg_splice_finish(sta->sdata, tid);
- ieee80211_agg_start_txq(sta, tid, false);
kfree_rcu(tid_tx, rcu_head);
}
@@ -451,58 +449,13 @@
ieee80211_stop_tx_ba_session(&sta->sta, tid);
}
-void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
+static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
+ struct tid_ampdu_tx *tid_tx)
{
- struct tid_ampdu_tx *tid_tx;
- struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata;
- struct ieee80211_ampdu_params params = {
- .sta = &sta->sta,
- .action = IEEE80211_AMPDU_TX_START,
- .tid = tid,
- .buf_size = 0,
- .amsdu = false,
- .timeout = 0,
- };
- int ret;
+ struct ieee80211_local *local = sta->local;
+ u8 tid = tid_tx->tid;
u16 buf_size;
-
- tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
-
- /*
- * Start queuing up packets for this aggregation session.
- * We're going to release them once the driver is OK with
- * that.
- */
- clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
-
- ieee80211_agg_stop_txq(sta, tid);
-
- /*
- * Make sure no packets are being processed. This ensures that
- * we have a valid starting sequence number and that in-flight
- * packets have been flushed out and no packets for this TID
- * will go into the driver during the ampdu_action call.
- */
- synchronize_net();
-
- params.ssn = sta->tid_seq[tid] >> 4;
- ret = drv_ampdu_action(local, sdata, ¶ms);
- if (ret) {
- ht_dbg(sdata,
- "BA request denied - HW unavailable for %pM tid %d\n",
- sta->sta.addr, tid);
- spin_lock_bh(&sta->lock);
- ieee80211_agg_splice_packets(sdata, tid_tx, tid);
- ieee80211_assign_tid_tx(sta, tid, NULL);
- ieee80211_agg_splice_finish(sdata, tid);
- spin_unlock_bh(&sta->lock);
-
- ieee80211_agg_start_txq(sta, tid, false);
-
- kfree_rcu(tid_tx, rcu_head);
- return;
- }
/* activate the timer for the recipient's addBA response */
mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
@@ -528,8 +481,79 @@
/* send AddBA request */
ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
- tid_tx->dialog_token, params.ssn,
+ tid_tx->dialog_token, tid_tx->ssn,
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)
+{
+ struct tid_ampdu_tx *tid_tx;
+ struct ieee80211_local *local = sta->local;
+ struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_ampdu_params params = {
+ .sta = &sta->sta,
+ .action = IEEE80211_AMPDU_TX_START,
+ .tid = tid,
+ .buf_size = 0,
+ .amsdu = false,
+ .timeout = 0,
+ };
+ int ret;
+
+ tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+
+ /*
+ * Start queuing up packets for this aggregation session.
+ * We're going to release them once the driver is OK with
+ * that.
+ */
+ clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
+
+ ieee80211_agg_stop_txq(sta, tid);
+
+ /*
+ * Make sure no packets are being processed. This ensures that
+ * we have a valid starting sequence number and that in-flight
+ * packets have been flushed out and no packets for this TID
+ * will go into the driver during the ampdu_action call.
+ */
+ synchronize_net();
+
+ sdata = sta->sdata;
+ params.ssn = sta->tid_seq[tid] >> 4;
+ ret = drv_ampdu_action(local, sdata, ¶ms);
+ tid_tx->ssn = params.ssn;
+ 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
+ * ready immediately.
+ */
+ set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state);
+ } else if (ret) {
+ if (!sdata)
+ return;
+
+ ht_dbg(sdata,
+ "BA request denied - HW unavailable for %pM tid %d\n",
+ sta->sta.addr, tid);
+ spin_lock_bh(&sta->lock);
+ ieee80211_agg_splice_packets(sdata, tid_tx, tid);
+ ieee80211_assign_tid_tx(sta, tid, NULL);
+ ieee80211_agg_splice_finish(sdata, tid);
+ spin_unlock_bh(&sta->lock);
+
+ ieee80211_agg_start_txq(sta, tid, false);
+
+ kfree_rcu(tid_tx, rcu_head);
+ return;
+ }
+
+ ieee80211_send_addba_with_timeout(sta, tid_tx);
}
/*
@@ -574,7 +598,8 @@
"Requested to start BA session on reserved tid=%d", tid))
return -EINVAL;
- if (!pubsta->ht_cap.ht_supported)
+ if (!pubsta->ht_cap.ht_supported &&
+ sta->sdata->vif.bss_conf.chandef.chan->band != NL80211_BAND_6GHZ)
return -EINVAL;
if (WARN_ON_ONCE(!local->ops->ampdu_action))
@@ -601,6 +626,14 @@
if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
ht_dbg(sdata,
"BA sessions blocked - Denying BA session request %pM tid %d\n",
+ sta->sta.addr, tid);
+ return -EINVAL;
+ }
+
+ if (test_sta_flag(sta, WLAN_STA_MFP) &&
+ !test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
+ ht_dbg(sdata,
+ "MFP STA not authorized - deny BA session request %pM tid %d\n",
sta->sta.addr, tid);
return -EINVAL;
}
@@ -750,6 +783,12 @@
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);
}
@@ -863,6 +902,7 @@
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
bool send_delba = false;
+ bool start_txq = false;
ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n",
sta->sta.addr, tid);
@@ -880,10 +920,14 @@
send_delba = true;
ieee80211_remove_tid_tx(sta, tid);
+ start_txq = true;
unlock_sta:
spin_unlock_bh(&sta->lock);
+ if (start_txq)
+ ieee80211_agg_start_txq(sta, tid, false);
+
if (send_delba)
ieee80211_send_delba(sdata, sta->sta.addr, tid,
WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
--
Gitblit v1.6.2