Commit cb6ebbdf authored by Howard Hsu's avatar Howard Hsu Committed by Felix Fietkau
Browse files

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: default avatarHoward Hsu <howard-yh.hsu@mediatek.com>
Link: https://patch.msgid.link/20250909-mt7996-addba-txd-fix-v1-1-feec16f0c6f0@kernel.org


Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 9557b6fe
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -294,6 +294,13 @@ enum tx_frag_idx {
#define MT_TXP_BUF_LEN			GENMASK(11, 0)
#define MT_TXP_DMA_ADDR_H		GENMASK(15, 12)

#define MT_TXP0_TOKEN_ID0		GENMASK(14, 0)
#define MT_TXP0_TOKEN_ID0_VALID_MASK	BIT(15)

#define MT_TXP1_TID_ADDBA		GENMASK(14, 12)
#define MT_TXP3_ML0_MASK		BIT(15)
#define MT_TXP3_DMA_ADDR_H		GENMASK(13, 12)

#define MT_TX_RATE_STBC			BIT(14)
#define MT_TX_RATE_NSS			GENMASK(13, 10)
#define MT_TX_RATE_MODE			GENMASK(9, 6)
+62 −29
Original line number Diff line number Diff line
@@ -802,6 +802,9 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
	    mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
		if (is_mt7990(&dev->mt76))
			txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TID_ADDBA, tid));
		else
			txwi[7] |= cpu_to_le32(MT_TXD7_MAC_TXD);

		tid = MT_TX_ADDBA;
	} else if (ieee80211_is_mgmt(hdr->frame_control)) {
		tid = MT_TX_NORMAL;
@@ -1035,10 +1038,10 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
	struct ieee80211_key_conf *key = info->control.hw_key;
	struct ieee80211_vif *vif = info->control.vif;
	struct mt76_connac_txp_common *txp;
	struct mt76_txwi_cache *t;
	int id, i, pid, nbuf = tx_info->nbuf - 1;
	bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
	__le32 *ptr = (__le32 *)txwi_ptr;
	u8 *txwi = (u8 *)txwi_ptr;

	if (unlikely(tx_info->skb->len <= ETH_HLEN))
@@ -1096,6 +1099,35 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
		mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
				      pid, qid, 0);

	/* MT7996 and MT7992 require driver to provide the MAC TXP for AddBA
	 * req
	 */
	if (le32_to_cpu(ptr[7]) & MT_TXD7_MAC_TXD) {
		u32 val;

		ptr = (__le32 *)(txwi + MT_TXD_SIZE);
		memset((void *)ptr, 0, sizeof(struct mt76_connac_fw_txp));

		val = FIELD_PREP(MT_TXP0_TOKEN_ID0, id) |
		      MT_TXP0_TOKEN_ID0_VALID_MASK;
		ptr[0] = cpu_to_le32(val);

		val = FIELD_PREP(MT_TXP1_TID_ADDBA,
				 tx_info->skb->priority &
				 IEEE80211_QOS_CTL_TID_MASK);
		ptr[1] = cpu_to_le32(val);
		ptr[2] = cpu_to_le32(tx_info->buf[1].addr & 0xFFFFFFFF);

		val = FIELD_PREP(MT_TXP_BUF_LEN, tx_info->buf[1].len) |
		      MT_TXP3_ML0_MASK;
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
		val |= FIELD_PREP(MT_TXP3_DMA_ADDR_H,
				  tx_info->buf[1].addr >> 32);
#endif
		ptr[3] = cpu_to_le32(val);
	} else {
		struct mt76_connac_txp_common *txp;

		txp = (struct mt76_connac_txp_common *)(txwi + MT_TXD_SIZE);
		for (i = 0; i < nbuf; i++) {
			u16 len;
@@ -1136,6 +1168,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,

		txp->fw.token = cpu_to_le16(id);
		txp->fw.rept_wds_wcid = cpu_to_le16(sta ? wcid->idx : 0xfff);
	}

	tx_info->skb = NULL;