Skip to content

Commit 8620dfb

Browse files
haogrootnbd168
authored andcommitted
wifi: mt76: mt7996: support writing MAC TXD for AddBA Request
Support writing MAC TXD for the AddBA Req. Without this commit, the start sequence number in AddBA Req will be unexpected value for MT7996 and MT7992. This can result in certain stations (e.g., AX200) dropping packets, leading to ping failures and degraded connectivity. Ensuring the correct MAC TXD and TXP helps maintain reliable packet transmission and prevents interoperability issues with affected stations. Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com> Link: https://patch.msgid.link/20250909-mt7996-addba-txd-fix-v1-1-feec16f0c6f0@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent f3c8e66 commit 8620dfb

2 files changed

Lines changed: 69 additions & 29 deletions

File tree

drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,13 @@ enum tx_frag_idx {
294294
#define MT_TXP_BUF_LEN GENMASK(11, 0)
295295
#define MT_TXP_DMA_ADDR_H GENMASK(15, 12)
296296

297+
#define MT_TXP0_TOKEN_ID0 GENMASK(14, 0)
298+
#define MT_TXP0_TOKEN_ID0_VALID_MASK BIT(15)
299+
300+
#define MT_TXP1_TID_ADDBA GENMASK(14, 12)
301+
#define MT_TXP3_ML0_MASK BIT(15)
302+
#define MT_TXP3_DMA_ADDR_H GENMASK(13, 12)
303+
297304
#define MT_TX_RATE_STBC BIT(14)
298305
#define MT_TX_RATE_NSS GENMASK(13, 10)
299306
#define MT_TX_RATE_MODE GENMASK(9, 6)

drivers/net/wireless/mediatek/mt76/mt7996/mac.c

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,9 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
802802
mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
803803
if (is_mt7990(&dev->mt76))
804804
txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TID_ADDBA, tid));
805+
else
806+
txwi[7] |= cpu_to_le32(MT_TXD7_MAC_TXD);
807+
805808
tid = MT_TX_ADDBA;
806809
} else if (ieee80211_is_mgmt(hdr->frame_control)) {
807810
tid = MT_TX_NORMAL;
@@ -1031,10 +1034,10 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
10311034
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
10321035
struct ieee80211_key_conf *key = info->control.hw_key;
10331036
struct ieee80211_vif *vif = info->control.vif;
1034-
struct mt76_connac_txp_common *txp;
10351037
struct mt76_txwi_cache *t;
10361038
int id, i, pid, nbuf = tx_info->nbuf - 1;
10371039
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
1040+
__le32 *ptr = (__le32 *)txwi_ptr;
10381041
u8 *txwi = (u8 *)txwi_ptr;
10391042

10401043
if (unlikely(tx_info->skb->len <= ETH_HLEN))
@@ -1092,46 +1095,76 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
10921095
mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
10931096
pid, qid, 0);
10941097

1095-
txp = (struct mt76_connac_txp_common *)(txwi + MT_TXD_SIZE);
1096-
for (i = 0; i < nbuf; i++) {
1097-
u16 len;
1098+
/* MT7996 and MT7992 require driver to provide the MAC TXP for AddBA
1099+
* req
1100+
*/
1101+
if (le32_to_cpu(ptr[7]) & MT_TXD7_MAC_TXD) {
1102+
u32 val;
1103+
1104+
ptr = (__le32 *)(txwi + MT_TXD_SIZE);
1105+
memset((void *)ptr, 0, sizeof(struct mt76_connac_fw_txp));
1106+
1107+
val = FIELD_PREP(MT_TXP0_TOKEN_ID0, id) |
1108+
MT_TXP0_TOKEN_ID0_VALID_MASK;
1109+
ptr[0] = cpu_to_le32(val);
10981110

1099-
len = FIELD_PREP(MT_TXP_BUF_LEN, tx_info->buf[i + 1].len);
1111+
val = FIELD_PREP(MT_TXP1_TID_ADDBA,
1112+
tx_info->skb->priority &
1113+
IEEE80211_QOS_CTL_TID_MASK);
1114+
ptr[1] = cpu_to_le32(val);
1115+
ptr[2] = cpu_to_le32(tx_info->buf[1].addr & 0xFFFFFFFF);
1116+
1117+
val = FIELD_PREP(MT_TXP_BUF_LEN, tx_info->buf[1].len) |
1118+
MT_TXP3_ML0_MASK;
11001119
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
1101-
len |= FIELD_PREP(MT_TXP_DMA_ADDR_H,
1102-
tx_info->buf[i + 1].addr >> 32);
1120+
val |= FIELD_PREP(MT_TXP3_DMA_ADDR_H,
1121+
tx_info->buf[1].addr >> 32);
11031122
#endif
1123+
ptr[3] = cpu_to_le32(val);
1124+
} else {
1125+
struct mt76_connac_txp_common *txp;
11041126

1105-
txp->fw.buf[i] = cpu_to_le32(tx_info->buf[i + 1].addr);
1106-
txp->fw.len[i] = cpu_to_le16(len);
1107-
}
1108-
txp->fw.nbuf = nbuf;
1127+
txp = (struct mt76_connac_txp_common *)(txwi + MT_TXD_SIZE);
1128+
for (i = 0; i < nbuf; i++) {
1129+
u16 len;
1130+
1131+
len = FIELD_PREP(MT_TXP_BUF_LEN, tx_info->buf[i + 1].len);
1132+
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
1133+
len |= FIELD_PREP(MT_TXP_DMA_ADDR_H,
1134+
tx_info->buf[i + 1].addr >> 32);
1135+
#endif
11091136

1110-
txp->fw.flags = cpu_to_le16(MT_CT_INFO_FROM_HOST);
1137+
txp->fw.buf[i] = cpu_to_le32(tx_info->buf[i + 1].addr);
1138+
txp->fw.len[i] = cpu_to_le16(len);
1139+
}
1140+
txp->fw.nbuf = nbuf;
11111141

1112-
if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
1113-
txp->fw.flags |= cpu_to_le16(MT_CT_INFO_APPLY_TXD);
1142+
txp->fw.flags = cpu_to_le16(MT_CT_INFO_FROM_HOST);
11141143

1115-
if (!key)
1116-
txp->fw.flags |= cpu_to_le16(MT_CT_INFO_NONE_CIPHER_FRAME);
1144+
if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
1145+
txp->fw.flags |= cpu_to_le16(MT_CT_INFO_APPLY_TXD);
11171146

1118-
if (!is_8023 && mt7996_tx_use_mgmt(dev, tx_info->skb))
1119-
txp->fw.flags |= cpu_to_le16(MT_CT_INFO_MGMT_FRAME);
1147+
if (!key)
1148+
txp->fw.flags |= cpu_to_le16(MT_CT_INFO_NONE_CIPHER_FRAME);
11201149

1121-
if (vif) {
1122-
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
1123-
struct mt76_vif_link *mlink = NULL;
1150+
if (!is_8023 && mt7996_tx_use_mgmt(dev, tx_info->skb))
1151+
txp->fw.flags |= cpu_to_le16(MT_CT_INFO_MGMT_FRAME);
11241152

1125-
if (wcid->offchannel)
1126-
mlink = rcu_dereference(mvif->mt76.offchannel_link);
1127-
if (!mlink)
1128-
mlink = rcu_dereference(mvif->mt76.link[wcid->link_id]);
1153+
if (vif) {
1154+
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
1155+
struct mt76_vif_link *mlink = NULL;
11291156

1130-
txp->fw.bss_idx = mlink ? mlink->idx : mvif->deflink.mt76.idx;
1131-
}
1157+
if (wcid->offchannel)
1158+
mlink = rcu_dereference(mvif->mt76.offchannel_link);
1159+
if (!mlink)
1160+
mlink = rcu_dereference(mvif->mt76.link[wcid->link_id]);
1161+
1162+
txp->fw.bss_idx = mlink ? mlink->idx : mvif->deflink.mt76.idx;
1163+
}
11321164

1133-
txp->fw.token = cpu_to_le16(id);
1134-
txp->fw.rept_wds_wcid = cpu_to_le16(sta ? wcid->idx : 0xfff);
1165+
txp->fw.token = cpu_to_le16(id);
1166+
txp->fw.rept_wds_wcid = cpu_to_le16(sta ? wcid->idx : 0xfff);
1167+
}
11351168

11361169
tx_info->skb = NULL;
11371170

0 commit comments

Comments
 (0)