wifi: mt76: mt7996: HW ATF support

Add hardware airtime fairness (ATF) support for mt7996, using the MAC's
weighted DWRR scheduler (VoW) to balance TX airtime between stations, in
the same way as the mt7915 implementation.

This supplements mac80211's software airtime fairness rather than
replacing it: software ATF keeps scheduling the host TX queues, while the
hardware scheduler enforces fairness on the offloaded path where the host
has no airtime accounting, such as when WED is active.

A station's TX airtime weight is taken from mac80211 through the
sta_set_airtime_weight op and applied to the hardware scheduler directly;
the per-AC DWRR quantum levels and the station's BSS group index are
derived on the fly, mapping the weight logarithmically onto the global
hardware quantum table. ATF and WATF are enabled by default and can be
toggled together at runtime through the "vow_atf" debugfs file.

Signed-off-by: Benjamin Lin <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2026-06-30 09:55:10 +02:00
parent 6b7b98627b
commit 910db36ae5
6 changed files with 308 additions and 12 deletions
+32
View File
@@ -1995,6 +1995,37 @@ mt7996_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return 0;
}
static void mt7996_sta_set_airtime_weight(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 weight)
{
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
struct mt7996_dev *dev = mt7996_hw_dev(hw);
struct ieee80211_link_sta *link_sta;
unsigned int link_id;
mutex_lock(&dev->mt76.mutex);
for_each_sta_active_link(vif, sta, link_sta, link_id) {
struct mt7996_sta_link *msta_link;
struct mt7996_vif_link *link;
link = mt7996_vif_link(dev, vif, link_id);
if (!link)
continue;
msta_link = mt7996_sta_link_protected(dev, msta, link_id);
if (!msta_link || !msta_link->wcid.sta)
continue;
mt7996_mcu_set_vow_drr_ctrl(dev, link->mt76.band_idx,
&msta_link->wcid, &link->mt76,
VOW_DRR_CTRL_STA_ALL, weight);
}
mutex_unlock(&dev->mt76.mutex);
}
static void mt7996_sta_set_4addr(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -2553,6 +2584,7 @@ const struct ieee80211_ops mt7996_ops = {
.sta_statistics = mt7996_sta_statistics,
.sta_set_4addr = mt7996_sta_set_4addr,
.sta_set_decap_offload = mt7996_sta_set_decap_offload,
.sta_set_airtime_weight = mt7996_sta_set_airtime_weight,
.add_twt_setup = mt7996_mac_add_twt_setup,
.twt_teardown_request = mt7996_twt_teardown_request,
#ifdef CONFIG_MAC80211_DEBUGFS