Skip to content

Commit f0b0b23

Browse files
csyuancnbd168
authored andcommitted
wifi: mt76: mt7996: rework mt7996_mac_write_txwi() for MLO support
Update mt7996_mac_write_txwi routine and all the called subroutines to support MLO. 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-4-015b3d6fd928@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent c1d6dd5 commit f0b0b23

File tree

1 file changed

+41
-14
lines changed
  • drivers/net/wireless/mediatek/mt76/mt7996

1 file changed

+41
-14
lines changed

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

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -730,9 +730,8 @@ mt7996_mac_write_txwi_8023(struct mt7996_dev *dev, __le32 *txwi,
730730
u32 val;
731731

732732
if (wcid->sta) {
733-
struct ieee80211_sta *sta;
733+
struct ieee80211_sta *sta = wcid_to_sta(wcid);
734734

735-
sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
736735
wmm = sta->wme;
737736
}
738737

@@ -759,14 +758,17 @@ mt7996_mac_write_txwi_8023(struct mt7996_dev *dev, __le32 *txwi,
759758

760759
static void
761760
mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
762-
struct sk_buff *skb, struct ieee80211_key_conf *key)
761+
struct sk_buff *skb,
762+
struct ieee80211_key_conf *key,
763+
struct mt76_wcid *wcid)
763764
{
764765
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
765766
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
766767
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
767768
bool multicast = is_multicast_ether_addr(hdr->addr1);
768769
u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
769770
__le16 fc = hdr->frame_control, sc = hdr->seq_ctrl;
771+
u16 seqno = le16_to_cpu(sc);
770772
u8 fc_type, fc_stype;
771773
u32 val;
772774

@@ -816,9 +818,13 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
816818
txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
817819
}
818820

819-
if (info->flags & IEEE80211_TX_CTL_INJECTED) {
820-
u16 seqno = le16_to_cpu(sc);
821+
if (multicast && ieee80211_vif_is_mld(info->control.vif)) {
822+
val = MT_TXD3_SN_VALID |
823+
FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
824+
txwi[3] |= cpu_to_le32(val);
825+
}
821826

827+
if (info->flags & IEEE80211_TX_CTL_INJECTED) {
822828
if (ieee80211_is_back_req(hdr->frame_control)) {
823829
struct ieee80211_bar *bar;
824830

@@ -831,6 +837,19 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
831837
txwi[3] |= cpu_to_le32(val);
832838
txwi[3] &= ~cpu_to_le32(MT_TXD3_HW_AMSDU);
833839
}
840+
841+
if (ieee80211_vif_is_mld(info->control.vif) &&
842+
(multicast || unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))))
843+
txwi[5] |= cpu_to_le32(MT_TXD5_FL);
844+
845+
if (ieee80211_is_nullfunc(fc) && ieee80211_has_a4(fc) &&
846+
ieee80211_vif_is_mld(info->control.vif)) {
847+
txwi[5] |= cpu_to_le32(MT_TXD5_FL);
848+
txwi[6] |= cpu_to_le32(MT_TXD6_DIS_MAT);
849+
}
850+
851+
if (!wcid->sta && ieee80211_is_mgmt(fc))
852+
txwi[6] |= cpu_to_le32(MT_TXD6_DIS_MAT);
834853
}
835854

836855
void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
@@ -846,20 +865,23 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
846865
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
847866
struct mt76_vif_link *mlink = NULL;
848867
struct mt7996_vif *mvif;
868+
unsigned int link_id;
849869
u16 tx_count = 15;
850870
u32 val;
851871
bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
852872
BSS_CHANGED_FILS_DISCOVERY));
853873
bool beacon = !!(changed & (BSS_CHANGED_BEACON |
854874
BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc);
855875

856-
if (vif) {
857-
mvif = (struct mt7996_vif *)vif->drv_priv;
858-
if (wcid->offchannel)
859-
mlink = rcu_dereference(mvif->mt76.offchannel_link);
860-
if (!mlink)
861-
mlink = &mvif->deflink.mt76;
862-
}
876+
if (wcid != &dev->mt76.global_wcid)
877+
link_id = wcid->link_id;
878+
else
879+
link_id = u32_get_bits(info->control.flags,
880+
IEEE80211_TX_CTRL_MLO_LINK);
881+
882+
mvif = vif ? (struct mt7996_vif *)vif->drv_priv : NULL;
883+
if (mvif)
884+
mlink = rcu_dereference(mvif->mt76.link[link_id]);
863885

864886
if (mlink) {
865887
omac_idx = mlink->omac_idx;
@@ -911,7 +933,10 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
911933
val |= MT_TXD5_TX_STATUS_HOST;
912934
txwi[5] = cpu_to_le32(val);
913935

914-
val = MT_TXD6_DIS_MAT | MT_TXD6_DAS;
936+
val = MT_TXD6_DAS;
937+
if (q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0)
938+
val |= MT_TXD6_DIS_MAT;
939+
915940
if (is_mt7996(&dev->mt76))
916941
val |= FIELD_PREP(MT_TXD6_MSDU_CNT, 1);
917942
else if (is_8023 || !ieee80211_is_mgmt(hdr->frame_control))
@@ -923,7 +948,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
923948
if (is_8023)
924949
mt7996_mac_write_txwi_8023(dev, txwi, skb, wcid);
925950
else
926-
mt7996_mac_write_txwi_80211(dev, txwi, skb, key);
951+
mt7996_mac_write_txwi_80211(dev, txwi, skb, key, wcid);
927952

928953
if (txwi[1] & cpu_to_le32(MT_TXD1_FIXED_RATE)) {
929954
bool mcast = ieee80211_is_data(hdr->frame_control) &&
@@ -940,6 +965,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
940965
}
941966

942967
val = FIELD_PREP(MT_TXD6_TX_RATE, idx) | MT_TXD6_FIXED_BW;
968+
if (mcast)
969+
val |= MT_TXD6_DIS_MAT;
943970
txwi[6] |= cpu_to_le32(val);
944971
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
945972
}

0 commit comments

Comments
 (0)