summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShayne Chen <shayne.chen@mediatek.com>2025-03-12 12:13:50 +0100
committerFelix Fietkau <nbd@nbd.name>2025-03-19 14:47:06 +0100
commit7464b12b7d92b9641d4664735b9f3c3f0b6173d9 (patch)
tree152453e3ccec1db2946813949b7895baa20af2fb
parent19db942418f53959f6d9b6fb60fe43268552fe01 (diff)
wifi: mt76: mt7996: rework mt7996_rx_get_wcid to support MLO
The wcid idx and band idx in the TXS are sometimes mismatched since the FW will select a transmission link according to a private algorithm. That is, the wcid idx in the TXS would be the one registered by the driver rather than the actual wcid idx used during transmission. However, the band idx in the TXS is the band select for transmission. Therefore, we should get the driver-registered wcid in order to notify the driver the packet has been acked; otherwise, the driver will be unable to match the transmitted packet and its TXS. This is a preliminary patch to enable MLO for MT7996 driver. Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com> Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com> Co-developed-by: Peter Chiu <chui-hao.chiu@mediatek.com> Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com> Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://patch.msgid.link/20250312-b4-mt7996-mlo-p2-v1-6-015b3d6fd928@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mac.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 9f8436edc813..b8d88fdee97a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -53,29 +53,48 @@ static const struct mt7996_dfs_radar_spec jp_radar_specs = {
};
static struct mt76_wcid *mt7996_rx_get_wcid(struct mt7996_dev *dev,
- u16 idx, bool unicast)
+ u16 idx, u8 band_idx)
{
struct mt7996_sta_link *msta_link;
struct mt7996_sta *msta;
+ struct mt7996_vif *mvif;
struct mt76_wcid *wcid;
+ int i;
if (idx >= ARRAY_SIZE(dev->mt76.wcid))
return NULL;
wcid = rcu_dereference(dev->mt76.wcid[idx]);
- if (unicast || !wcid)
- return wcid;
+ if (!wcid)
+ return NULL;
- if (!wcid->sta)
+ if (!mt7996_band_valid(dev, band_idx))
return NULL;
+ if (wcid->phy_idx == band_idx)
+ return wcid;
+
msta_link = container_of(wcid, struct mt7996_sta_link, wcid);
msta = msta_link->sta;
-
if (!msta || !msta->vif)
return NULL;
- return &msta->vif->deflink.msta_link.wcid;
+ mvif = msta->vif;
+ for (i = 0; i < ARRAY_SIZE(mvif->mt76.link); i++) {
+ struct mt76_vif_link *mlink;
+
+ mlink = rcu_dereference(mvif->mt76.link[i]);
+ if (!mlink)
+ continue;
+
+ if (mlink->band_idx != band_idx)
+ continue;
+
+ msta_link = rcu_dereference(msta->link[i]);
+ break;
+ }
+
+ return &msta_link->wcid;
}
bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask)
@@ -483,7 +502,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
- status->wcid = mt7996_rx_get_wcid(dev, idx, unicast);
+ status->wcid = mt7996_rx_get_wcid(dev, idx, band_idx);
if (status->wcid) {
struct mt7996_sta_link *msta_link;