|
Takashi Iwai |
115ed5 |
From 1a89bb2cec93bc7a4e384387b382d08ce14cc354 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
115ed5 |
From: Chris Chiu <chris.chiu@canonical.com>
|
|
Takashi Iwai |
115ed5 |
Date: Wed, 4 Aug 2021 23:13:25 +0800
|
|
Takashi Iwai |
115ed5 |
Subject: [PATCH] rtl8xxxu: Fix the handling of TX A-MPDU aggregation
|
|
Takashi Iwai |
115ed5 |
Git-commit: 95a581ab3592082c60a08090aabe09ac7d0bd650
|
|
Takashi Iwai |
115ed5 |
Patch-mainline: v5.15-rc1
|
|
Takashi Iwai |
115ed5 |
References: stable-5.14.6
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
[ Upstream commit 95a581ab3592082c60a08090aabe09ac7d0bd650 ]
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
The TX A-MPDU aggregation is not handled in the driver since the
|
|
Takashi Iwai |
115ed5 |
ieee80211_start_tx_ba_session has never been started properly.
|
|
Takashi Iwai |
115ed5 |
Start and stop the TX BA session by tracking the TX aggregation
|
|
Takashi Iwai |
115ed5 |
status of each TID. Fix the ampdu_action and the tx descriptor
|
|
Takashi Iwai |
115ed5 |
accordingly with the given TID.
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
Signed-off-by: Chris Chiu <chris.chiu@canonical.com>
|
|
Takashi Iwai |
115ed5 |
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
|
Takashi Iwai |
115ed5 |
Link: https://lore.kernel.org/r/20210804151325.86600-1-chris.chiu@canonical.com
|
|
Takashi Iwai |
115ed5 |
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
Takashi Iwai |
115ed5 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
---
|
|
Takashi Iwai |
115ed5 |
.../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 2 ++
|
|
Takashi Iwai |
115ed5 |
.../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 33 ++++++++++++++-----
|
|
Takashi Iwai |
115ed5 |
2 files changed, 26 insertions(+), 9 deletions(-)
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
|
|
Takashi Iwai |
115ed5 |
index 01735776345a..7ddce3c3f0c4 100644
|
|
Takashi Iwai |
115ed5 |
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
|
|
Takashi Iwai |
115ed5 |
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
|
|
Takashi Iwai |
115ed5 |
@@ -1378,6 +1378,8 @@ struct rtl8xxxu_priv {
|
|
Takashi Iwai |
115ed5 |
u8 no_pape:1;
|
|
Takashi Iwai |
115ed5 |
u8 int_buf[USB_INTR_CONTENT_LENGTH];
|
|
Takashi Iwai |
115ed5 |
u8 rssi_level;
|
|
Takashi Iwai |
115ed5 |
+ DECLARE_BITMAP(tx_aggr_started, IEEE80211_NUM_TIDS);
|
|
Takashi Iwai |
115ed5 |
+ DECLARE_BITMAP(tid_tx_operational, IEEE80211_NUM_TIDS);
|
|
Takashi Iwai |
115ed5 |
/*
|
|
Takashi Iwai |
115ed5 |
* Only one virtual interface permitted because only STA mode
|
|
Takashi Iwai |
115ed5 |
* is supported and no iface_combinations are provided.
|
|
Takashi Iwai |
115ed5 |
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
|
|
Takashi Iwai |
115ed5 |
index ac1061caacd6..3285a91efb91 100644
|
|
Takashi Iwai |
115ed5 |
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
|
|
Takashi Iwai |
115ed5 |
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
|
|
Takashi Iwai |
115ed5 |
@@ -4805,6 +4805,8 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
|
Takashi Iwai |
115ed5 |
struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
|
|
Takashi Iwai |
115ed5 |
struct rtl8xxxu_priv *priv = hw->priv;
|
|
Takashi Iwai |
115ed5 |
struct device *dev = &priv->udev->dev;
|
|
Takashi Iwai |
115ed5 |
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
|
|
Takashi Iwai |
115ed5 |
+ u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
|
|
Takashi Iwai |
115ed5 |
u32 rate;
|
|
Takashi Iwai |
115ed5 |
u16 rate_flags = tx_info->control.rates[0].flags;
|
|
Takashi Iwai |
115ed5 |
u16 seq_number;
|
|
Takashi Iwai |
115ed5 |
@@ -4828,7 +4830,7 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
tx_desc->txdw3 = cpu_to_le32((u32)seq_number << TXDESC32_SEQ_SHIFT);
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
- if (ampdu_enable)
|
|
Takashi Iwai |
115ed5 |
+ if (ampdu_enable && test_bit(tid, priv->tid_tx_operational))
|
|
Takashi Iwai |
115ed5 |
tx_desc->txdw1 |= cpu_to_le32(TXDESC32_AGG_ENABLE);
|
|
Takashi Iwai |
115ed5 |
else
|
|
Takashi Iwai |
115ed5 |
tx_desc->txdw1 |= cpu_to_le32(TXDESC32_AGG_BREAK);
|
|
Takashi Iwai |
115ed5 |
@@ -4876,6 +4878,8 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
|
Takashi Iwai |
115ed5 |
struct rtl8xxxu_priv *priv = hw->priv;
|
|
Takashi Iwai |
115ed5 |
struct device *dev = &priv->udev->dev;
|
|
Takashi Iwai |
115ed5 |
struct rtl8xxxu_txdesc40 *tx_desc40;
|
|
Takashi Iwai |
115ed5 |
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
|
|
Takashi Iwai |
115ed5 |
+ u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
|
|
Takashi Iwai |
115ed5 |
u32 rate;
|
|
Takashi Iwai |
115ed5 |
u16 rate_flags = tx_info->control.rates[0].flags;
|
|
Takashi Iwai |
115ed5 |
u16 seq_number;
|
|
Takashi Iwai |
115ed5 |
@@ -4902,7 +4906,7 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
tx_desc40->txdw9 = cpu_to_le32((u32)seq_number << TXDESC40_SEQ_SHIFT);
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
- if (ampdu_enable)
|
|
Takashi Iwai |
115ed5 |
+ if (ampdu_enable && test_bit(tid, priv->tid_tx_operational))
|
|
Takashi Iwai |
115ed5 |
tx_desc40->txdw2 |= cpu_to_le32(TXDESC40_AGG_ENABLE);
|
|
Takashi Iwai |
115ed5 |
else
|
|
Takashi Iwai |
115ed5 |
tx_desc40->txdw2 |= cpu_to_le32(TXDESC40_AGG_BREAK);
|
|
Takashi Iwai |
115ed5 |
@@ -5015,12 +5019,19 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
|
|
Takashi Iwai |
115ed5 |
if (ieee80211_is_data_qos(hdr->frame_control) && sta) {
|
|
Takashi Iwai |
115ed5 |
if (sta->ht_cap.ht_supported) {
|
|
Takashi Iwai |
115ed5 |
u32 ampdu, val32;
|
|
Takashi Iwai |
115ed5 |
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
|
|
Takashi Iwai |
115ed5 |
+ u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
ampdu = (u32)sta->ht_cap.ampdu_density;
|
|
Takashi Iwai |
115ed5 |
val32 = ampdu << TXDESC_AMPDU_DENSITY_SHIFT;
|
|
Takashi Iwai |
115ed5 |
tx_desc->txdw2 |= cpu_to_le32(val32);
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
ampdu_enable = true;
|
|
Takashi Iwai |
115ed5 |
+
|
|
Takashi Iwai |
115ed5 |
+ if (!test_bit(tid, priv->tx_aggr_started) &&
|
|
Takashi Iwai |
115ed5 |
+ !(skb->protocol == cpu_to_be16(ETH_P_PAE)))
|
|
Takashi Iwai |
115ed5 |
+ if (!ieee80211_start_tx_ba_session(sta, tid, 0))
|
|
Takashi Iwai |
115ed5 |
+ set_bit(tid, priv->tx_aggr_started);
|
|
Takashi Iwai |
115ed5 |
}
|
|
Takashi Iwai |
115ed5 |
}
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
@@ -6096,6 +6107,7 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
Takashi Iwai |
115ed5 |
struct device *dev = &priv->udev->dev;
|
|
Takashi Iwai |
115ed5 |
u8 ampdu_factor, ampdu_density;
|
|
Takashi Iwai |
115ed5 |
struct ieee80211_sta *sta = params->sta;
|
|
Takashi Iwai |
115ed5 |
+ u16 tid = params->tid;
|
|
Takashi Iwai |
115ed5 |
enum ieee80211_ampdu_mlme_action action = params->action;
|
|
Takashi Iwai |
115ed5 |
|
|
Takashi Iwai |
115ed5 |
switch (action) {
|
|
Takashi Iwai |
115ed5 |
@@ -6108,17 +6120,20 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
Takashi Iwai |
115ed5 |
dev_dbg(dev,
|
|
Takashi Iwai |
115ed5 |
"Changed HT: ampdu_factor %02x, ampdu_density %02x\n",
|
|
Takashi Iwai |
115ed5 |
ampdu_factor, ampdu_density);
|
|
Takashi Iwai |
115ed5 |
- break;
|
|
Takashi Iwai |
115ed5 |
+ return IEEE80211_AMPDU_TX_START_IMMEDIATE;
|
|
Takashi Iwai |
115ed5 |
+ case IEEE80211_AMPDU_TX_STOP_CONT:
|
|
Takashi Iwai |
115ed5 |
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
|
Takashi Iwai |
115ed5 |
- dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_STOP_FLUSH\n", __func__);
|
|
Takashi Iwai |
115ed5 |
- rtl8xxxu_set_ampdu_factor(priv, 0);
|
|
Takashi Iwai |
115ed5 |
- rtl8xxxu_set_ampdu_min_space(priv, 0);
|
|
Takashi Iwai |
115ed5 |
- break;
|
|
Takashi Iwai |
115ed5 |
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
|
Takashi Iwai |
115ed5 |
- dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_STOP_FLUSH_CONT\n",
|
|
Takashi Iwai |
115ed5 |
- __func__);
|
|
Takashi Iwai |
115ed5 |
+ dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_STOP\n", __func__);
|
|
Takashi Iwai |
115ed5 |
rtl8xxxu_set_ampdu_factor(priv, 0);
|
|
Takashi Iwai |
115ed5 |
rtl8xxxu_set_ampdu_min_space(priv, 0);
|
|
Takashi Iwai |
115ed5 |
+ clear_bit(tid, priv->tx_aggr_started);
|
|
Takashi Iwai |
115ed5 |
+ clear_bit(tid, priv->tid_tx_operational);
|
|
Takashi Iwai |
115ed5 |
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
|
Takashi Iwai |
115ed5 |
+ break;
|
|
Takashi Iwai |
115ed5 |
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
|
|
Takashi Iwai |
115ed5 |
+ dev_dbg(dev, "%s: IEEE80211_AMPDU_TX_OPERATIONAL\n", __func__);
|
|
Takashi Iwai |
115ed5 |
+ set_bit(tid, priv->tid_tx_operational);
|
|
Takashi Iwai |
115ed5 |
break;
|
|
Takashi Iwai |
115ed5 |
case IEEE80211_AMPDU_RX_START:
|
|
Takashi Iwai |
115ed5 |
dev_dbg(dev, "%s: IEEE80211_AMPDU_RX_START\n", __func__);
|
|
Takashi Iwai |
115ed5 |
--
|
|
Takashi Iwai |
115ed5 |
2.26.2
|
|
Takashi Iwai |
115ed5 |
|