[PATCH v1 4/4] wifi: ath11k: report tx airtime and enable airtime fairness

Julius Bairaktaris <[email protected]>
Newsgroups org.kernel.vger.linux-wireless,org.infradead.lists.ath11k
Message-ID <[email protected]>
mac80211's airtime scheduler charges sta->airtime[ac].deficit from one
place, ieee80211_sta_register_airtime(). Unlike AQL there is no estimator
fallback, and ath11k never calls it, so the ATF feature bit cannot be
advertised on its own: the deficit would only ever be
replenished, every station would stay permanently in credit, and the DRR
would be inert. The bit is not a no-op in that state either, because it
also moves txq insertion to the head of the active list, which
__ieee80211_schedule_txq() documents as safe only because the DRR moves a
station back once its deficit goes negative.

fes_duration_us arrives with every PPDU's stats and is already
accumulated into arsta->tx_duration a few lines above. Register it, and
set the feature bit in the same change so the two cannot be separated.

Measured on an IPQ8074 AP with two stations on one radio, a 1x1 VHT
client at 433 Mbit/s and a 2x2 HE client, both receiving at once. Before,
'iw station set <mac> airtime_weight' is refused with -EOPNOTSUPP and the
per-station airtime file reads zero. After, the weight is accepted and
read back, TX airtime accumulates, and the per-AC deficits move.

The fairness this delivers is coarse. Weighting the fast station 4:1 moves
the slow station's share of airtime from 59.5% to 52.1% and the fast
station's throughput from 315 to 392 Mbit/s: the direction is correct, the
magnitude is not the ratio requested. The granularity is bounded by the
driver's push model, since ieee80211_handle_wake_tx_queue() drains a
selected txq whole into the hardware and the scheduler therefore reorders
only between selections. Tightening the AQL limit to shorten those drains
does not improve it: the share moves by one point and aggregate
throughput falls from 401 to 178 Mbit/s. Finer control would require a TXQ
scheduler in the driver.

Two properties of the source are worth stating. fes_duration_us spans the
frame exchange sequence, so it includes the SIFS and the responding
BlockAck, time the radio spends receiving; the airtime registered is
therefore larger than the airtime transmitted. And it is a per-PPDU field,
so on a downlink MU PPDU each user is charged the whole sequence. No
per-user duration is reported in these stats. On the firmware tested here
every PPDU carried exactly one user, measured over 21051 PPDUs, so the MU
case is latent rather than observed.

Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.9.0.1-02146-QCAHKSWPL_SILICONZ-1
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <[email protected]>
---
 drivers/net/wireless/ath/ath11k/dp_rx.c | 9 +++++++++
 drivers/net/wireless/ath/ath11k/mac.c   | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 33425707c084..33c6fd9553a6 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1485,6 +1485,15 @@ ath11k_update_per_peer_tx_stats(struct ath11k *ar,
 
 	arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(bw);
 	arsta->tx_duration += tx_duration;
+
+	/* tid is HTT_PPDU_STATS_NON_QOS_TID when no ack/BA TLV came with the
+	 * PPDU; mask it so that airtime lands in a real access category rather
+	 * than one chosen by the spare bits.
+	 */
+	if (tx_duration)
+		ieee80211_sta_register_airtime(sta,
+					       tid & IEEE80211_QOS_CTL_TID_MASK,
+					       tx_duration, 0);
 	memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info));
 
 	/* PPDU stats reported for mgmt packet doesn't have valid tx bytes.
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 38f641bbc53c..40a2b6d2f804 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -10593,6 +10593,8 @@ static int __ath11k_mac_register(struct ath11k *ar)
 
 	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
 	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL);
+	wiphy_ext_feature_set(ar->hw->wiphy,
+			      NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
 	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
 	if (test_bit(WMI_TLV_SERVICE_BSS_COLOR_OFFLOAD,
 		     ar->ab->wmi_ab.svc_map)) {
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.