From: Charlie-cy Wu On connac2 chipsets - MT7920, MT7921 and MT7922 - the spe_idx of fixed-rate frames was never programmed, so every management frame - auth and assoc req included - went out 1SS 1T on WF0 instead of 1SS 2T duplicate, giving up ~3dB of array gain during connection setup, which is exactly when the link budget is worst. mt76_connac2_mac_write_txwi() takes the MT_TXD2_FIX_RATE path for any non-data frame, but the block filling MT_TXD7_SPE_IDX was guarded by !is_connac2(), leaving the field at 0. As spe_idx 0 also encodes "WF0" the hardware happily transmitted on a single path. Drop the guard so connac2 fills the index like the other generations do. Do not set MT_TXD6_SPE_ID_IDX along with it: on connac2 that bit points the hardware at the WTBL instead of the TXD, and the WTBL spe_idx is still 0 while connecting, so setting it puts the frames back on WF0. This matches connac3, where SPE_IXD_SELECT_TXD is 0 and SPE_IXD_SELECT_BMC_WTBL is 1, and is the opposite of what the falcon firmware macro name HAL_MAC_TX_DESC_SET_FR_SPE_IDX_SPE_BY_TXD suggests. Guard the duplicate fallback with hweight8() as well: ant_to_spe[] maps a single-antenna mask to 0 too, so without the check a user asking for one antenna would still get spe_idx 24 and duplicate onto both paths. Verified on MT7922: TXD DW7 spe_idx now reads 0x18 and the in-chip sniffer reports spe_idx 0x18 in the TXV of auth and assoc req, where it previously reported 0x0. MT7920 and MT7921 share the same connac2 TXD path and are fixed by the same change. Fixes: 00dd59264dcb ("wifi: mt76: connac: use is_connac2() to replace is_mt7921() checks") Signed-off-by: Charlie-cy Wu --- v2: remove Bora-id commit message --- .../wireless/mediatek/mt76/mt76_connac_mac.c | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c index de38ba9a4a26..9b40bac2b036 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c @@ -600,6 +600,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, vif ? &vif->bss_conf : NULL, beacon, multicast); u32 val = MT_TXD6_FIXED_BW; + u8 spe_idx = mt76_connac_spe_idx(mphy->antenna_mask); /* hardware won't add HTC for mgmt/ctrl frame */ txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD); @@ -608,13 +609,18 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, txwi[6] |= cpu_to_le32(val); txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); - if (!is_connac2(dev)) { - u8 spe_idx = mt76_connac_spe_idx(mphy->antenna_mask); - - if (!spe_idx) - spe_idx = 24 + phy_idx; - txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, spe_idx)); - } + /* Fixed-rate frames (all mgmt, so auth/assoc req too) otherwise + * carry spe_idx 0 and TX 1SS 1T on WF0. Fill spe_idx like the + * other connac generations do, but do NOT touch + * MT_TXD6_SPE_ID_IDX: on connac2 setting it points HW at the + * WTBL and the index below is ignored. + * + * spe_idx 0 is also a valid single-path index (WF0), so only + * take the duplicate fallback when a second path exists. + */ + if (!spe_idx && hweight8(mphy->antenna_mask) > 1) + spe_idx = 24 + phy_idx; + txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, spe_idx)); txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU); } -- 2.18.0