* [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes
@ 2025-07-04 13:08 Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 1/9] wifi: mt76: fix vif link allocation Lorenzo Bianconi
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
Multiple MLO fixes for MT7996 driver in the mixed MLO/non-MLO scenario.
---
Felix Fietkau (1):
wifi: mt76: fix vif link allocation
Lorenzo Bianconi (8):
wifi: mt76: mt7996: Fix secondary link lookup in mt7996_mcu_sta_mld_setup_tlv()
wifi: mt76: mt7996: Rely on for_each_sta_active_link() in mt7996_mcu_sta_mld_setup_tlv()
wifi: mt76: mt7996: Do not set wcid.sta to 1 in mt7996_mac_sta_event()
wifi: mt76: mt7996: Fix mlink lookup in mt7996_tx_prepare_skb
wifi: mt76: mt7996: Fix possible OOB access in mt7996_tx()
wifi: mt76: mt7996: Fix valid_links bitmask in mt7996_mac_sta_{add,remove}
wifi: mt76: mt7996: Add MLO support to mt7996_tx_check_aggr()
wifi: mt76: mt7996: Move num_sta accounting in mt7996_mac_sta_{add,remove}_links
drivers/net/wireless/mediatek/mt76/channel.c | 4 +-
drivers/net/wireless/mediatek/mt76/mt76.h | 5 +-
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 48 +++++++-------
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 80 ++++++++++++++----------
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 17 +++--
5 files changed, 83 insertions(+), 71 deletions(-)
---
base-commit: b3a431fe2e399b2e0cc5f43f7e9d63d63d3710ee
change-id: 20250704-mt7996-mlo-fixes-ec842bcc890b
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH mt76 1/9] wifi: mt76: fix vif link allocation
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 2/9] wifi: mt76: mt7996: Fix secondary link lookup in mt7996_mcu_sta_mld_setup_tlv() Lorenzo Bianconi
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek
From: Felix Fietkau <nbd@nbd.name>
Reuse the vif deflink for link_id = 0 in order to avoid confusion with
vif->bss_conf, which also gets a link id of 0.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/channel.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76.h | 5 ++++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/channel.c b/drivers/net/wireless/mediatek/mt76/channel.c
index cc2d888e3f17a58512e6282686b446109ec7ab3c..77b75792eb488e9c5da9ca8026c04157182c13a4 100644
--- a/drivers/net/wireless/mediatek/mt76/channel.c
+++ b/drivers/net/wireless/mediatek/mt76/channel.c
@@ -173,13 +173,13 @@ void mt76_unassign_vif_chanctx(struct ieee80211_hw *hw,
if (!mlink)
goto out;
- if (link_conf != &vif->bss_conf)
+ if (mlink != (struct mt76_vif_link *)vif->drv_priv)
rcu_assign_pointer(mvif->link[link_id], NULL);
dev->drv->vif_link_remove(phy, vif, link_conf, mlink);
mlink->ctx = NULL;
- if (link_conf != &vif->bss_conf)
+ if (mlink != (struct mt76_vif_link *)vif->drv_priv)
kfree_rcu(mlink, rcu_head);
out:
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 14927a92f9d1b313253158c0e53dce8fab9fba18..022d83bb03da1803440c942c9343b709d76aecd4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1865,6 +1865,9 @@ mt76_vif_link(struct mt76_dev *dev, struct ieee80211_vif *vif, int link_id)
struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv;
struct mt76_vif_data *mvif = mlink->mvif;
+ if (!link_id)
+ return mlink;
+
return mt76_dereference(mvif->link[link_id], dev);
}
@@ -1875,7 +1878,7 @@ mt76_vif_conf_link(struct mt76_dev *dev, struct ieee80211_vif *vif,
struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv;
struct mt76_vif_data *mvif = mlink->mvif;
- if (link_conf == &vif->bss_conf)
+ if (link_conf == &vif->bss_conf || !link_conf->link_id)
return mlink;
return mt76_dereference(mvif->link[link_conf->link_id], dev);
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH mt76 2/9] wifi: mt76: mt7996: Fix secondary link lookup in mt7996_mcu_sta_mld_setup_tlv()
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 1/9] wifi: mt76: fix vif link allocation Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 3/9] wifi: mt76: mt7996: Rely on for_each_sta_active_link() " Lorenzo Bianconi
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
Use proper link_id value for secondary link lookup in
mt7996_mcu_sta_mld_setup_tlv routine.
Fixes: 00cef41d9d8f5 ("wifi: mt76: mt7996: Add mt7996_mcu_sta_mld_setup_tlv() and mt7996_mcu_sta_eht_mld_tlv()")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index f0adc0b4b8b6ccdc6ce11991a4d99b89500fe7a9..1bf5632cb0f754d49ec6201254d35652d23c0a8c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -2243,8 +2243,7 @@ mt7996_mcu_sta_mld_setup_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
if (nlinks > 1) {
link_id = __ffs(links & ~BIT(msta->deflink_id));
- msta_link = mt76_dereference(msta->link[msta->deflink_id],
- &dev->mt76);
+ msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
if (!msta_link)
return;
}
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH mt76 3/9] wifi: mt76: mt7996: Rely on for_each_sta_active_link() in mt7996_mcu_sta_mld_setup_tlv()
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 1/9] wifi: mt76: fix vif link allocation Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 2/9] wifi: mt76: mt7996: Fix secondary link lookup in mt7996_mcu_sta_mld_setup_tlv() Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 4/9] wifi: mt76: mt7996: Do not set wcid.sta to 1 in mt7996_mac_sta_event() Lorenzo Bianconi
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
Reuse for_each_sta_active_link utility macro in
mt7996_mcu_sta_mld_setup_tlv routine.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index 1bf5632cb0f754d49ec6201254d35652d23c0a8c..0374872db4777cc85eed594f7d977dd822927b6d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -2216,15 +2216,15 @@ mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif,
static void
mt7996_mcu_sta_mld_setup_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+ struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
- unsigned long links = sta->valid_links;
- unsigned int nlinks = hweight16(links);
+ unsigned int nlinks = hweight16(sta->valid_links);
struct mld_setup_link *mld_setup_link;
+ struct ieee80211_link_sta *link_sta;
struct sta_rec_mld_setup *mld_setup;
struct mt7996_sta_link *msta_link;
- struct ieee80211_vif *vif;
unsigned int link_id;
struct tlv *tlv;
@@ -2242,7 +2242,7 @@ mt7996_mcu_sta_mld_setup_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
mld_setup->primary_id = cpu_to_le16(msta_link->wcid.idx);
if (nlinks > 1) {
- link_id = __ffs(links & ~BIT(msta->deflink_id));
+ link_id = __ffs(sta->valid_links & ~BIT(msta->deflink_id));
msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
if (!msta_link)
return;
@@ -2250,9 +2250,8 @@ mt7996_mcu_sta_mld_setup_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
mld_setup->seconed_id = cpu_to_le16(msta_link->wcid.idx);
mld_setup->link_num = nlinks;
- vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
mld_setup_link = (struct mld_setup_link *)mld_setup->link_info;
- for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
+ for_each_sta_active_link(vif, sta, link_sta, link_id) {
struct mt7996_vif_link *link;
msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
@@ -2344,7 +2343,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev,
mt7996_mcu_sta_muru_tlv(dev, skb, link_conf, link_sta);
if (sta->mlo) {
- mt7996_mcu_sta_mld_setup_tlv(dev, skb, sta);
+ mt7996_mcu_sta_mld_setup_tlv(dev, skb, link_conf->vif,
+ sta);
mt7996_mcu_sta_eht_mld_tlv(dev, skb, sta);
}
}
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH mt76 4/9] wifi: mt76: mt7996: Do not set wcid.sta to 1 in mt7996_mac_sta_event()
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
` (2 preceding siblings ...)
2025-07-04 13:08 ` [PATCH mt76 3/9] wifi: mt76: mt7996: Rely on for_each_sta_active_link() " Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 5/9] wifi: mt76: mt7996: Fix mlink lookup in mt7996_tx_prepare_skb Lorenzo Bianconi
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
msta_link->wcid.sta is already set to 1 in mt7996_mac_sta_init_link
routine.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 5283aee619a9811f2e75fa4434ceced9185991f0..d1f90dea512bade652743611b7d062863a63ccfe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1119,7 +1119,6 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif,
return err;
msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET;
- msta_link->wcid.sta = 1;
break;
case MT76_STA_EVENT_AUTHORIZE:
err = mt7996_mcu_add_sta(dev, link_conf, link_sta,
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH mt76 5/9] wifi: mt76: mt7996: Fix mlink lookup in mt7996_tx_prepare_skb
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
` (3 preceding siblings ...)
2025-07-04 13:08 ` [PATCH mt76 4/9] wifi: mt76: mt7996: Do not set wcid.sta to 1 in mt7996_mac_sta_event() Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 6/9] wifi: mt76: mt7996: Fix possible OOB access in mt7996_tx() Lorenzo Bianconi
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
Use proper link_id in mt7996_tx_prepare_skb routine for mlink lookup.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 0dbd4662bc842947abf09f9ae3aa4a1d4b86cba8..0844f27b8458fe53c0765ece70fe91acdfc6510a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -1087,9 +1087,9 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
if (wcid->offchannel)
mlink = rcu_dereference(mvif->mt76.offchannel_link);
if (!mlink)
- mlink = &mvif->deflink.mt76;
+ mlink = rcu_dereference(mvif->mt76.link[wcid->link_id]);
- txp->fw.bss_idx = mlink->idx;
+ txp->fw.bss_idx = mlink ? mlink->idx : mvif->deflink.mt76.idx;
}
txp->fw.token = cpu_to_le16(id);
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH mt76 6/9] wifi: mt76: mt7996: Fix possible OOB access in mt7996_tx()
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
` (4 preceding siblings ...)
2025-07-04 13:08 ` [PATCH mt76 5/9] wifi: mt76: mt7996: Fix mlink lookup in mt7996_tx_prepare_skb Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 7/9] wifi: mt76: mt7996: Fix valid_links bitmask in mt7996_mac_sta_{add,remove} Lorenzo Bianconi
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
Fis possible Out-Of-Boundary access in mt7996_tx routine if link_id is
set to IEEE80211_LINK_UNSPECIFIED
Fixes: 3ce8acb86b661 ("wifi: mt76: mt7996: Update mt7996_tx to MLO support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index d1f90dea512bade652743611b7d062863a63ccfe..6404514556419f75b69a783d96b0920157263e04 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1216,10 +1216,17 @@ static void mt7996_tx(struct ieee80211_hw *hw,
if (vif) {
struct mt7996_vif *mvif = (void *)vif->drv_priv;
- struct mt76_vif_link *mlink;
+ struct mt76_vif_link *mlink = &mvif->deflink.mt76;
- mlink = rcu_dereference(mvif->mt76.link[link_id]);
- if (mlink && mlink->wcid)
+ if (link_id < IEEE80211_LINK_UNSPECIFIED)
+ mlink = rcu_dereference(mvif->mt76.link[link_id]);
+
+ if (!mlink) {
+ ieee80211_free_txskb(hw, skb);
+ goto unlock;
+ }
+
+ if (mlink->wcid)
wcid = mlink->wcid;
if (mvif->mt76.roc_phy &&
@@ -1228,7 +1235,7 @@ static void mt7996_tx(struct ieee80211_hw *hw,
if (mphy->roc_link)
wcid = mphy->roc_link->wcid;
} else {
- mphy = mt76_vif_link_phy(&mvif->deflink.mt76);
+ mphy = mt76_vif_link_phy(mlink);
}
}
@@ -1237,7 +1244,7 @@ static void mt7996_tx(struct ieee80211_hw *hw,
goto unlock;
}
- if (control->sta) {
+ if (control->sta && link_id < IEEE80211_LINK_UNSPECIFIED) {
struct mt7996_sta *msta = (void *)control->sta->drv_priv;
struct mt7996_sta_link *msta_link;
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH mt76 7/9] wifi: mt76: mt7996: Fix valid_links bitmask in mt7996_mac_sta_{add,remove}
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
` (5 preceding siblings ...)
2025-07-04 13:08 ` [PATCH mt76 6/9] wifi: mt76: mt7996: Fix possible OOB access in mt7996_tx() Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 8/9] wifi: mt76: mt7996: Add MLO support to mt7996_tx_check_aggr() Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 9/9] wifi: mt76: mt7996: Move num_sta accounting in mt7996_mac_sta_{add,remove}_links Lorenzo Bianconi
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
sta->valid_links bitmask can be set even for non-MLO client.
Fixes: dd82a9e02c054 ("wifi: mt76: mt7996: Rely on mt7996_sta_link in sta_add/sta_remove callbacks")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 6404514556419f75b69a783d96b0920157263e04..ea0cdd092a3f396c2a8cb655ff941b833fb9983e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1061,7 +1061,7 @@ mt7996_mac_sta_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,
struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
- unsigned long links = sta->mlo ? sta->valid_links : BIT(0);
+ unsigned long links = sta->valid_links ? sta->valid_links : BIT(0);
int err;
mutex_lock(&mdev->mutex);
@@ -1155,7 +1155,7 @@ mt7996_mac_sta_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif,
{
struct mt76_dev *mdev = mphy->dev;
struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
- unsigned long links = sta->mlo ? sta->valid_links : BIT(0);
+ unsigned long links = sta->valid_links ? sta->valid_links : BIT(0);
mutex_lock(&mdev->mutex);
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH mt76 8/9] wifi: mt76: mt7996: Add MLO support to mt7996_tx_check_aggr()
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
` (6 preceding siblings ...)
2025-07-04 13:08 ` [PATCH mt76 7/9] wifi: mt76: mt7996: Fix valid_links bitmask in mt7996_mac_sta_{add,remove} Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 9/9] wifi: mt76: mt7996: Move num_sta accounting in mt7996_mac_sta_{add,remove}_links Lorenzo Bianconi
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
Generalize mt7996_tx_check_aggr() and mt7996_txwi_free() routines to
introduce MLO support for MT7996 driver.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 44 ++++++++++++-------------
1 file changed, 21 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 0844f27b8458fe53c0765ece70fe91acdfc6510a..02e10d744feb45048401ef15e74c3e03b53b5e08 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -1129,15 +1129,14 @@ u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
}
static void
-mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
+mt7996_tx_check_aggr(struct ieee80211_link_sta *link_sta,
+ struct mt76_wcid *wcid, struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
- struct mt7996_sta_link *msta_link;
- struct mt7996_sta *msta;
u16 fc, tid;
- if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
+ if (!(link_sta->ht_cap.ht_supported || link_sta->he_cap.has_he))
return;
tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
@@ -1146,7 +1145,8 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
if (is_8023) {
fc = IEEE80211_FTYPE_DATA |
- (sta->wme ? IEEE80211_STYPE_QOS_DATA : IEEE80211_STYPE_DATA);
+ (link_sta->sta->wme ? IEEE80211_STYPE_QOS_DATA
+ : IEEE80211_STYPE_DATA);
} else {
/* No need to get precise TID for Action/Management Frame,
* since it will not meet the following Frame Control
@@ -1162,19 +1162,16 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
return;
- msta = (struct mt7996_sta *)sta->drv_priv;
- msta_link = &msta->deflink;
-
- if (!test_and_set_bit(tid, &msta_link->wcid.ampdu_state))
- ieee80211_start_tx_ba_session(sta, tid, 0);
+ if (!test_and_set_bit(tid, &wcid->ampdu_state))
+ ieee80211_start_tx_ba_session(link_sta->sta, tid, 0);
}
static void
mt7996_txwi_free(struct mt7996_dev *dev, struct mt76_txwi_cache *t,
- struct ieee80211_sta *sta, struct list_head *free_list)
+ struct ieee80211_link_sta *link_sta,
+ struct mt76_wcid *wcid, struct list_head *free_list)
{
struct mt76_dev *mdev = &dev->mt76;
- struct mt76_wcid *wcid;
__le32 *txwi;
u16 wcid_idx;
@@ -1183,12 +1180,10 @@ mt7996_txwi_free(struct mt7996_dev *dev, struct mt76_txwi_cache *t,
goto out;
txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t);
- if (sta) {
- wcid = (struct mt76_wcid *)sta->drv_priv;
+ if (link_sta) {
wcid_idx = wcid->idx;
-
if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
- mt7996_tx_check_aggr(sta, t->skb);
+ mt7996_tx_check_aggr(link_sta, wcid, t->skb);
} else {
wcid_idx = le32_get_bits(txwi[9], MT_TXD9_WLAN_IDX);
}
@@ -1207,8 +1202,8 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
struct mt76_dev *mdev = &dev->mt76;
struct mt76_phy *phy2 = mdev->phys[MT_BAND1];
struct mt76_phy *phy3 = mdev->phys[MT_BAND2];
+ struct ieee80211_link_sta *link_sta = NULL;
struct mt76_txwi_cache *txwi;
- struct ieee80211_sta *sta = NULL;
struct mt76_wcid *wcid = NULL;
LIST_HEAD(free_list);
struct sk_buff *skb, *tmp;
@@ -1245,7 +1240,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
*/
info = le32_to_cpu(*cur_info);
if (info & MT_TXFREE_INFO_PAIR) {
- struct mt7996_sta_link *msta_link;
+ struct ieee80211_sta *sta;
u16 idx;
idx = FIELD_GET(MT_TXFREE_INFO_WLAN_ID, info);
@@ -1254,9 +1249,11 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
if (!sta)
goto next;
- msta_link = container_of(wcid, struct mt7996_sta_link,
- wcid);
- mt76_wcid_add_poll(&dev->mt76, &msta_link->wcid);
+ link_sta = rcu_dereference(sta->link[wcid->link_id]);
+ if (!link_sta)
+ goto next;
+
+ mt76_wcid_add_poll(&dev->mt76, wcid);
next:
/* ver 7 has a new DW with pair = 1, skip it */
if (ver == 7 && ((void *)(cur_info + 1) < end) &&
@@ -1289,7 +1286,8 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
if (!txwi)
continue;
- mt7996_txwi_free(dev, txwi, sta, &free_list);
+ mt7996_txwi_free(dev, txwi, link_sta, wcid,
+ &free_list);
}
}
@@ -1748,7 +1746,7 @@ void mt7996_tx_token_put(struct mt7996_dev *dev)
spin_lock_bh(&dev->mt76.token_lock);
idr_for_each_entry(&dev->mt76.token, txwi, id) {
- mt7996_txwi_free(dev, txwi, NULL, NULL);
+ mt7996_txwi_free(dev, txwi, NULL, NULL, NULL);
dev->mt76.token_count--;
}
spin_unlock_bh(&dev->mt76.token_lock);
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH mt76 9/9] wifi: mt76: mt7996: Move num_sta accounting in mt7996_mac_sta_{add,remove}_links
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
` (7 preceding siblings ...)
2025-07-04 13:08 ` [PATCH mt76 8/9] wifi: mt76: mt7996: Add MLO support to mt7996_tx_check_aggr() Lorenzo Bianconi
@ 2025-07-04 13:08 ` Lorenzo Bianconi
8 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Bianconi @ 2025-07-04 13:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, Bo Jiao, Peter Chiu
Cc: linux-wireless, linux-arm-kernel, linux-mediatek,
Lorenzo Bianconi
Move phy num_sta accounting in mt7996_mac_sta_add() and
mt7996_mac_sta_remove() routines in order to take into account all
possibles MLO links.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 58 +++++++++++++-----------
1 file changed, 32 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index ea0cdd092a3f396c2a8cb655ff941b833fb9983e..f846b8309ae2e9c39f9d5f2a21ca1edd89dcdf0c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -960,8 +960,8 @@ mt7996_mac_sta_deinit_link(struct mt7996_dev *dev,
}
static void
-mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_sta *sta,
- unsigned long links)
+mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, unsigned long links)
{
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
struct mt76_dev *mdev = &dev->mt76;
@@ -969,6 +969,8 @@ mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_sta *sta,
for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
struct mt7996_sta_link *msta_link = NULL;
+ struct mt7996_vif_link *link;
+ struct mt76_phy *mphy;
msta_link = rcu_replace_pointer(msta->link[link_id], msta_link,
lockdep_is_held(&mdev->mutex));
@@ -976,6 +978,15 @@ mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_sta *sta,
continue;
mt7996_mac_sta_deinit_link(dev, msta_link);
+ link = mt7996_vif_link(dev, vif, link_id);
+ if (!link)
+ continue;
+
+ mphy = mt76_vif_link_phy(&link->mt76);
+ if (!mphy)
+ continue;
+
+ mphy->num_sta--;
if (msta->deflink_id == link_id) {
msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
continue;
@@ -997,6 +1008,7 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf;
struct ieee80211_link_sta *link_sta;
struct mt7996_vif_link *link;
+ struct mt76_phy *mphy;
if (rcu_access_pointer(msta->link[link_id]))
continue;
@@ -1023,12 +1035,19 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
link_id);
if (err)
goto error_unlink;
+
+ mphy = mt76_vif_link_phy(&link->mt76);
+ if (!mphy) {
+ err = -EINVAL;
+ goto error_unlink;
+ }
+ mphy->num_sta++;
}
return 0;
error_unlink:
- mt7996_mac_sta_remove_links(dev, sta, new_links);
+ mt7996_mac_sta_remove_links(dev, vif, sta, new_links);
return err;
}
@@ -1045,7 +1064,7 @@ mt7996_mac_sta_change_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&dev->mt76.mutex);
- mt7996_mac_sta_remove_links(dev, sta, rem);
+ mt7996_mac_sta_remove_links(dev, vif, sta, rem);
ret = mt7996_mac_sta_add_links(dev, vif, sta, add);
mutex_unlock(&dev->mt76.mutex);
@@ -1054,25 +1073,21 @@ mt7996_mac_sta_change_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
static int
-mt7996_mac_sta_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+mt7996_mac_sta_add(struct mt7996_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
- struct mt76_dev *mdev = mphy->dev;
- struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
unsigned long links = sta->valid_links ? sta->valid_links : BIT(0);
int err;
- mutex_lock(&mdev->mutex);
+ mutex_lock(&dev->mt76.mutex);
msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
msta->vif = mvif;
err = mt7996_mac_sta_add_links(dev, vif, sta, links);
- if (!err)
- mphy->num_sta++;
- mutex_unlock(&mdev->mutex);
+ mutex_unlock(&dev->mt76.mutex);
return err;
}
@@ -1150,19 +1165,14 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif,
}
static void
-mt7996_mac_sta_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+mt7996_mac_sta_remove(struct mt7996_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
- struct mt76_dev *mdev = mphy->dev;
- struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
unsigned long links = sta->valid_links ? sta->valid_links : BIT(0);
- mutex_lock(&mdev->mutex);
-
- mt7996_mac_sta_remove_links(dev, sta, links);
- mphy->num_sta--;
-
- mutex_unlock(&mdev->mutex);
+ mutex_lock(&dev->mt76.mutex);
+ mt7996_mac_sta_remove_links(dev, vif, sta, links);
+ mutex_unlock(&dev->mt76.mutex);
}
static int
@@ -1170,20 +1180,16 @@ mt7996_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, enum ieee80211_sta_state old_state,
enum ieee80211_sta_state new_state)
{
- struct mt76_phy *mphy = mt76_vif_phy(hw, vif);
struct mt7996_dev *dev = mt7996_hw_dev(hw);
enum mt76_sta_event ev;
- if (!mphy)
- return -EINVAL;
-
if (old_state == IEEE80211_STA_NOTEXIST &&
new_state == IEEE80211_STA_NONE)
- return mt7996_mac_sta_add(mphy, vif, sta);
+ return mt7996_mac_sta_add(dev, vif, sta);
if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST)
- mt7996_mac_sta_remove(mphy, vif, sta);
+ mt7996_mac_sta_remove(dev, vif, sta);
if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_ASSOC)
--
2.50.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-07-04 13:08 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-04 13:08 [PATCH mt76 0/9] wifi: mt76: mt7996: Various MLO fixes Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 1/9] wifi: mt76: fix vif link allocation Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 2/9] wifi: mt76: mt7996: Fix secondary link lookup in mt7996_mcu_sta_mld_setup_tlv() Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 3/9] wifi: mt76: mt7996: Rely on for_each_sta_active_link() " Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 4/9] wifi: mt76: mt7996: Do not set wcid.sta to 1 in mt7996_mac_sta_event() Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 5/9] wifi: mt76: mt7996: Fix mlink lookup in mt7996_tx_prepare_skb Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 6/9] wifi: mt76: mt7996: Fix possible OOB access in mt7996_tx() Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 7/9] wifi: mt76: mt7996: Fix valid_links bitmask in mt7996_mac_sta_{add,remove} Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 8/9] wifi: mt76: mt7996: Add MLO support to mt7996_tx_check_aggr() Lorenzo Bianconi
2025-07-04 13:08 ` [PATCH mt76 9/9] wifi: mt76: mt7996: Move num_sta accounting in mt7996_mac_sta_{add,remove}_links 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).