Commit 355f8d00 authored by Felix Fietkau's avatar Felix Fietkau
Browse files

mt76: mt76x02: track approximate tx airtime for airtime fairness and survey



Estimate by calculating duration for EWMA packet size + estimated A-MPDU
length on tx status events

Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent b02f42f4
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -276,3 +276,51 @@ u32 mt76_calc_rx_airtime(struct mt76_dev *dev, struct mt76_rx_status *status,

	return duration;
}

u32 mt76_calc_tx_airtime(struct mt76_dev *dev, struct ieee80211_tx_info *info,
			 int len)
{
	struct mt76_rx_status stat = {
		.band = info->band,
	};
	u32 duration = 0;
	int i;

	for (i = 0; i < ARRAY_SIZE(info->status.rates); i++) {
		struct ieee80211_tx_rate *rate = &info->status.rates[i];
		u32 cur_duration;

		if (rate->idx < 0 || !rate->count)
			break;

		if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
			stat.bw = RATE_INFO_BW_80;
		else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
			stat.bw = RATE_INFO_BW_40;
		else
			stat.bw = RATE_INFO_BW_20;

		stat.enc_flags = 0;
		if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
			stat.enc_flags |= RX_ENC_FLAG_SHORTPRE;
		if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
			stat.enc_flags |= RX_ENC_FLAG_SHORT_GI;

		stat.rate_idx = rate->idx;
		if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
			stat.encoding = RX_ENC_VHT;
			stat.rate_idx = ieee80211_rate_get_vht_mcs(rate);
			stat.nss = ieee80211_rate_get_vht_nss(rate);
		} else if (rate->flags & IEEE80211_TX_RC_MCS) {
			stat.encoding = RX_ENC_HT;
		} else {
			stat.encoding = RX_ENC_LEGACY;
		}

		cur_duration = mt76_calc_rx_airtime(dev, &stat, len);
		duration += cur_duration * rate->count;
	}

	return duration;
}
EXPORT_SYMBOL_GPL(mt76_calc_tx_airtime);
+2 −0
Original line number Diff line number Diff line
@@ -772,6 +772,8 @@ void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		  const u8 *mac);
void mt76_sw_scan_complete(struct ieee80211_hw *hw,
			   struct ieee80211_vif *vif);
u32 mt76_calc_tx_airtime(struct mt76_dev *dev, struct ieee80211_tx_info *info,
			 int len);

/* internal */
void mt76_tx_free(struct mt76_dev *dev);
+1 −0
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
		.txwi_size = sizeof(struct mt76x02_txwi),
		.drv_flags = MT_DRV_TX_ALIGNED4_SKBS |
			     MT_DRV_SW_RX_AIRTIME,
		.survey_flags = SURVEY_INFO_TIME_TX,
		.update_survey = mt76x02_update_channel,
		.tx_prepare_skb = mt76x02_tx_prepare_skb,
		.tx_complete_skb = mt76x02_tx_complete_skb,
+1 −0
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
{
	static const struct mt76_driver_ops drv_ops = {
		.drv_flags = MT_DRV_SW_RX_AIRTIME,
		.survey_flags = SURVEY_INFO_TIME_TX,
		.update_survey = mt76x02_update_channel,
		.tx_prepare_skb = mt76x02u_tx_prepare_skb,
		.tx_complete_skb = mt76x02u_tx_complete_skb,
+1 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ struct mt76x02_dev {
	u8 txdone_seq;
	DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
	spinlock_t txstatus_fifo_lock;
	u32 tx_airtime;

	struct sk_buff *rx_head;

Loading