* [PATCH mt76] wifi: mt76: mt7996: Use deflink for AMPDU rx reordering
@ 2025-08-23 14:55 Lorenzo Bianconi
0 siblings, 0 replies; only message in thread
From: Lorenzo Bianconi @ 2025-08-23 14:55 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
Packets belonging to the same TID can be sent over multiple links.
AMPDU rx reordering must be performed over all active links. Fix the
problem always using default link for AMPDU rx reordering.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/agg-rx.c | 2 +
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 10 ++-
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 97 ++++++++--------------
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 64 +++++++++++---
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 6 +-
5 files changed, 101 insertions(+), 78 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c
index 07c386c7b4d08967f5dcb69ee9282b042afbce10..936ab1ca92460793f4d275ad18dd6f7722445d90 100644
--- a/drivers/net/wireless/mediatek/mt76/agg-rx.c
+++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c
@@ -173,6 +173,8 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
if (ackp == IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
return;
+ if (wcid->def_wcid)
+ wcid = wcid->def_wcid;
tid = rcu_dereference(wcid->aggr[tidno]);
if (!tid)
return;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index d6531b74be1f15467c06e385d0efabad806db6b8..fecf68271234e7949014d5be6b9e2f87c6dbb281 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -1183,8 +1183,14 @@ mt7996_txwi_free(struct mt7996_dev *dev, struct mt76_txwi_cache *t,
txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t);
if (link_sta) {
wcid_idx = wcid->idx;
- if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
- mt7996_tx_check_aggr(link_sta, wcid, t->skb);
+ if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE))) {
+ struct mt7996_sta *msta;
+
+ /* AMPDU state is stored in the primary link */
+ msta = (void *)link_sta->sta->drv_priv;
+ mt7996_tx_check_aggr(link_sta, &msta->deflink.wcid,
+ t->skb);
+ }
} else {
wcid_idx = le32_get_bits(txwi[9], MT_TXD9_WLAN_IDX);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 38d15963ec5801e70b8e539b7707a8d47c9a37fd..16b208b0d1c7c529cb8ee4f5090a5ed4287aeddd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -988,11 +988,6 @@ static void
mt7996_mac_sta_deinit_link(struct mt7996_dev *dev,
struct mt7996_sta_link *msta_link)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(msta_link->wcid.aggr); i++)
- mt76_rx_aggr_stop(&dev->mt76, &msta_link->wcid, i);
-
mt7996_mac_wtbl_update(dev, msta_link->wcid.idx,
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
@@ -1367,16 +1362,13 @@ static int
mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_ampdu_params *params)
{
- enum ieee80211_ampdu_mlme_action action = params->action;
struct mt7996_dev *dev = mt7996_hw_dev(hw);
struct ieee80211_sta *sta = params->sta;
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
struct ieee80211_txq *txq = sta->txq[params->tid];
- struct ieee80211_link_sta *link_sta;
u16 tid = params->tid;
u16 ssn = params->ssn;
struct mt76_txq *mtxq;
- unsigned int link_id;
int ret = 0;
if (!txq)
@@ -1386,61 +1378,42 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&dev->mt76.mutex);
- for_each_sta_active_link(vif, sta, link_sta, link_id) {
- struct mt7996_sta_link *msta_link;
- struct mt7996_vif_link *link;
-
- msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
- if (!msta_link)
- continue;
-
- link = mt7996_vif_link(dev, vif, link_id);
- if (!link)
- continue;
-
- switch (action) {
- case IEEE80211_AMPDU_RX_START:
- mt76_rx_aggr_start(&dev->mt76, &msta_link->wcid, tid,
- ssn, params->buf_size);
- ret = mt7996_mcu_add_rx_ba(dev, params, link,
- msta_link, true);
- break;
- case IEEE80211_AMPDU_RX_STOP:
- mt76_rx_aggr_stop(&dev->mt76, &msta_link->wcid, tid);
- ret = mt7996_mcu_add_rx_ba(dev, params, link,
- msta_link, false);
- break;
- case IEEE80211_AMPDU_TX_OPERATIONAL:
- mtxq->aggr = true;
- mtxq->send_bar = false;
- ret = mt7996_mcu_add_tx_ba(dev, params, link,
- msta_link, true);
- break;
- case IEEE80211_AMPDU_TX_STOP_FLUSH:
- case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
- mtxq->aggr = false;
- clear_bit(tid, &msta_link->wcid.ampdu_state);
- ret = mt7996_mcu_add_tx_ba(dev, params, link,
- msta_link, false);
- break;
- case IEEE80211_AMPDU_TX_START:
- set_bit(tid, &msta_link->wcid.ampdu_state);
- ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
- break;
- case IEEE80211_AMPDU_TX_STOP_CONT:
- mtxq->aggr = false;
- clear_bit(tid, &msta_link->wcid.ampdu_state);
- ret = mt7996_mcu_add_tx_ba(dev, params, link,
- msta_link, false);
- break;
- }
-
- if (ret)
- break;
- }
-
- if (action == IEEE80211_AMPDU_TX_STOP_CONT)
+ switch (params->action) {
+ case IEEE80211_AMPDU_RX_START:
+ /* Since packets belonging to the same TID can be split over
+ * multiple links, store the AMPDU state for reordering in the
+ * primary link
+ */
+ mt76_rx_aggr_start(&dev->mt76, &msta->deflink.wcid, tid,
+ ssn, params->buf_size);
+ ret = mt7996_mcu_add_rx_ba(dev, params, vif, true);
+ break;
+ case IEEE80211_AMPDU_RX_STOP:
+ mt76_rx_aggr_stop(&dev->mt76, &msta->deflink.wcid, tid);
+ ret = mt7996_mcu_add_rx_ba(dev, params, vif, false);
+ break;
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ mtxq->aggr = true;
+ mtxq->send_bar = false;
+ ret = mt7996_mcu_add_tx_ba(dev, params, vif, true);
+ break;
+ case IEEE80211_AMPDU_TX_STOP_FLUSH:
+ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+ mtxq->aggr = false;
+ clear_bit(tid, &msta->deflink.wcid.ampdu_state);
+ ret = mt7996_mcu_add_tx_ba(dev, params, vif, false);
+ break;
+ case IEEE80211_AMPDU_TX_START:
+ set_bit(tid, &msta->deflink.wcid.ampdu_state);
+ ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
+ break;
+ case IEEE80211_AMPDU_TX_STOP_CONT:
+ mtxq->aggr = false;
+ clear_bit(tid, &msta->deflink.wcid.ampdu_state);
+ ret = mt7996_mcu_add_tx_ba(dev, params, vif, false);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ break;
+ }
mutex_unlock(&dev->mt76.mutex);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index 0ba60279bbb77dfa94ef3121f75eaadac3c7290e..f641cedf5d6a080baf9cb7d47bd60cabbb147fb0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -1192,23 +1192,67 @@ mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif_link *mvif,
/** starec & wtbl **/
int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
struct ieee80211_ampdu_params *params,
- struct mt7996_vif_link *link,
- struct mt7996_sta_link *msta_link, bool enable)
+ struct ieee80211_vif *vif, bool enable)
{
- if (enable && !params->amsdu)
- msta_link->wcid.amsdu = false;
+ struct ieee80211_sta *sta = params->sta;
+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ struct ieee80211_link_sta *link_sta;
+ unsigned int link_id;
+ int ret = 0;
+
+ for_each_sta_active_link(vif, sta, link_sta, link_id) {
+ struct mt7996_sta_link *msta_link;
+ struct mt7996_vif_link *link;
+
+ msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
+ if (!msta_link)
+ continue;
- return mt7996_mcu_sta_ba(dev, &link->mt76, params, &msta_link->wcid,
- enable, true);
+ link = mt7996_vif_link(dev, vif, link_id);
+ if (!link)
+ continue;
+
+ if (enable && !params->amsdu)
+ msta_link->wcid.amsdu = false;
+
+ ret = mt7996_mcu_sta_ba(dev, &link->mt76, params,
+ &msta_link->wcid, enable, true);
+ if (ret)
+ break;
+ }
+
+ return ret;
}
int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
struct ieee80211_ampdu_params *params,
- struct mt7996_vif_link *link,
- struct mt7996_sta_link *msta_link, bool enable)
+ struct ieee80211_vif *vif, bool enable)
{
- return mt7996_mcu_sta_ba(dev, &link->mt76, params, &msta_link->wcid,
- enable, false);
+ struct ieee80211_sta *sta = params->sta;
+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ struct ieee80211_link_sta *link_sta;
+ unsigned int link_id;
+ int ret = 0;
+
+ for_each_sta_active_link(vif, sta, link_sta, link_id) {
+ struct mt7996_sta_link *msta_link;
+ struct mt7996_vif_link *link;
+
+ msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
+ if (!msta_link)
+ continue;
+
+ link = mt7996_vif_link(dev, vif, link_id);
+ if (!link)
+ continue;
+
+ ret = mt7996_mcu_sta_ba(dev, &link->mt76, params,
+ &msta_link->wcid, enable, false);
+ if (ret)
+ break;
+ }
+
+ return ret;
}
static void
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index b98cfe6e5be8c6b77357cf7d2a76135f10609ca4..97b84710667ffdb5b6188a72d6f8475f7eb9a128 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -612,12 +612,10 @@ int mt7996_mcu_teardown_mld_sta(struct mt7996_dev *dev,
struct mt7996_sta_link *msta_link);
int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
struct ieee80211_ampdu_params *params,
- struct mt7996_vif_link *link,
- struct mt7996_sta_link *msta_link, bool enable);
+ struct ieee80211_vif *vif, bool enable);
int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
struct ieee80211_ampdu_params *params,
- struct mt7996_vif_link *link,
- struct mt7996_sta_link *msta_link, bool enable);
+ struct ieee80211_vif *vif, bool enable);
int mt7996_mcu_update_bss_color(struct mt7996_dev *dev,
struct mt76_vif_link *mlink,
struct cfg80211_he_bss_color *he_bss_color);
---
base-commit: d0698b9ec737e0d764fbe15805114d67822b0e75
change-id: 20250823-mt7996-mlo-aggr-fix-cc1d659facb3
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2025-08-23 14:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-23 14:55 [PATCH mt76] wifi: mt76: mt7996: Use deflink for AMPDU rx reordering Lorenzo Bianconi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).