From: "Toke Høiland-Jørgensen" <toke@redhat.com>
To: Felix Fietkau <nbd@nbd.name>, linux-wireless@vger.kernel.org
Subject: Re: [PATCH 05/15] mt76: track rx airtime for airtime fairness and survey
Date: Fri, 27 Sep 2019 10:35:59 +0200 [thread overview]
Message-ID: <87v9teyw40.fsf@toke.dk> (raw)
In-Reply-To: <20190926174732.42375-5-nbd@nbd.name>
Felix Fietkau <nbd@nbd.name> writes:
> Report total rx airtime for valid stations as BSS rx time in survey
>
> mt7615 is left out for now, it will be supported later by reading
> hardware counters instead of calculating airtime in software
>
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
> ---
> drivers/net/wireless/mediatek/mt76/Makefile | 2 +-
> drivers/net/wireless/mediatek/mt76/airtime.c | 278 ++++++++++++++++++
> drivers/net/wireless/mediatek/mt76/mac80211.c | 109 ++++++-
> drivers/net/wireless/mediatek/mt76/mt76.h | 64 ++--
> .../net/wireless/mediatek/mt76/mt7603/init.c | 1 +
> .../net/wireless/mediatek/mt76/mt7603/mac.c | 2 +-
> .../net/wireless/mediatek/mt76/mt7615/mac.c | 2 +-
> .../net/wireless/mediatek/mt76/mt76x0/pci.c | 3 +-
> .../net/wireless/mediatek/mt76/mt76x0/usb.c | 1 +
> .../net/wireless/mediatek/mt76/mt76x02_mac.c | 4 +-
> .../net/wireless/mediatek/mt76/mt76x2/pci.c | 3 +-
> .../net/wireless/mediatek/mt76/mt76x2/usb.c | 1 +
> 12 files changed, 433 insertions(+), 37 deletions(-)
> create mode 100644 drivers/net/wireless/mediatek/mt76/airtime.c
>
> diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile
> index 4d03596e891f..181af60e32db 100644
> --- a/drivers/net/wireless/mediatek/mt76/Makefile
> +++ b/drivers/net/wireless/mediatek/mt76/Makefile
> @@ -6,7 +6,7 @@ obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o
>
> mt76-y := \
> mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \
> - tx.o agg-rx.o mcu.o
> + tx.o agg-rx.o mcu.o airtime.o
>
> mt76-usb-y := usb.o usb_trace.o
>
> diff --git a/drivers/net/wireless/mediatek/mt76/airtime.c b/drivers/net/wireless/mediatek/mt76/airtime.c
> new file mode 100644
> index 000000000000..d5bc4d713a88
> --- /dev/null
> +++ b/drivers/net/wireless/mediatek/mt76/airtime.c
> @@ -0,0 +1,278 @@
> +// SPDX-License-Identifier: ISC
> +/*
> + * Copyright (C) 2019 Felix Fietkau <nbd@nbd.name>
> + */
> +
> +#include "mt76.h"
> +
> +#define AVG_PKT_SIZE 1024
> +
> +/* Number of bits for an average sized packet */
> +#define MCS_NBITS (AVG_PKT_SIZE << 3)
> +
> +/* Number of symbols for a packet with (bps) bits per symbol */
> +#define MCS_NSYMS(bps) DIV_ROUND_UP(MCS_NBITS, (bps))
> +
> +/* Transmission time (1024 usec) for a packet containing (syms) * symbols */
> +#define MCS_SYMBOL_TIME(sgi, syms) \
> + (sgi ? \
> + ((syms) * 18 * 1024 + 4 * 1024) / 5 : /* syms * 3.6 us */ \
> + ((syms) * 1024) << 2 /* syms * 4 us */ \
> + )
> +
> +/* Transmit duration for the raw data part of an average sized packet */
> +#define MCS_DURATION(streams, sgi, bps) \
> + MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps)))
> +
> +#define BW_20 0
> +#define BW_40 1
> +#define BW_80 2
> +
> +/*
> + * Define group sort order: HT40 -> SGI -> #streams
> + */
> +#define MT_MAX_STREAMS 4
> +#define MT_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */
> +#define MT_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */
> +
> +#define MT_HT_GROUPS_NB (MT_MAX_STREAMS * \
> + MT_HT_STREAM_GROUPS)
> +#define MT_VHT_GROUPS_NB (MT_MAX_STREAMS * \
> + MT_VHT_STREAM_GROUPS)
> +#define MT_GROUPS_NB (MT_HT_GROUPS_NB + \
> + MT_VHT_GROUPS_NB)
> +
> +#define MT_HT_GROUP_0 0
> +#define MT_VHT_GROUP_0 (MT_HT_GROUP_0 + MT_HT_GROUPS_NB)
> +
> +#define MCS_GROUP_RATES 10
> +
> +#define HT_GROUP_IDX(_streams, _sgi, _ht40) \
> + MT_HT_GROUP_0 + \
> + MT_MAX_STREAMS * 2 * _ht40 + \
> + MT_MAX_STREAMS * _sgi + \
> + _streams - 1
> +
> +#define _MAX(a, b) (((a)>(b))?(a):(b))
> +
> +#define GROUP_SHIFT(duration) \
> + _MAX(0, 16 - __builtin_clz(duration))
> +
> +/* MCS rate information for an MCS group */
> +#define __MCS_GROUP(_streams, _sgi, _ht40, _s) \
> + [HT_GROUP_IDX(_streams, _sgi, _ht40)] = { \
> + .shift = _s, \
> + .duration = { \
> + MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s, \
> + MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s, \
> + MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s, \
> + MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s, \
> + MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s, \
> + MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s, \
> + MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s, \
> + MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s \
> + } \
> +}
> +
> +#define MCS_GROUP_SHIFT(_streams, _sgi, _ht40) \
> + GROUP_SHIFT(MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26))
> +
> +#define MCS_GROUP(_streams, _sgi, _ht40) \
> + __MCS_GROUP(_streams, _sgi, _ht40, \
> + MCS_GROUP_SHIFT(_streams, _sgi, _ht40))
> +
> +#define VHT_GROUP_IDX(_streams, _sgi, _bw) \
> + (MT_VHT_GROUP_0 + \
> + MT_MAX_STREAMS * 2 * (_bw) + \
> + MT_MAX_STREAMS * (_sgi) + \
> + (_streams) - 1)
> +
> +#define BW2VBPS(_bw, r3, r2, r1) \
> + (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
> +
> +#define __VHT_GROUP(_streams, _sgi, _bw, _s) \
> + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \
> + .shift = _s, \
> + .duration = { \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 117, 54, 26)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 234, 108, 52)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 351, 162, 78)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 468, 216, 104)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 702, 324, 156)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 936, 432, 208)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 1053, 486, 234)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 1170, 540, 260)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 1404, 648, 312)) >> _s, \
> + MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 1560, 720, 346)) >> _s \
> + } \
> +}
> +
> +#define VHT_GROUP_SHIFT(_streams, _sgi, _bw) \
> + GROUP_SHIFT(MCS_DURATION(_streams, _sgi, \
> + BW2VBPS(_bw, 117, 54, 26)))
> +
> +#define VHT_GROUP(_streams, _sgi, _bw) \
> + __VHT_GROUP(_streams, _sgi, _bw, \
> + VHT_GROUP_SHIFT(_streams, _sgi, _bw))
> +
> +struct mcs_group {
> + u8 shift;
> + u16 duration[MCS_GROUP_RATES];
> +};
> +
> +static const struct mcs_group airtime_mcs_groups[] = {
> + MCS_GROUP(1, 0, BW_20),
> + MCS_GROUP(2, 0, BW_20),
> + MCS_GROUP(3, 0, BW_20),
> + MCS_GROUP(4, 0, BW_20),
> +
> + MCS_GROUP(1, 1, BW_20),
> + MCS_GROUP(2, 1, BW_20),
> + MCS_GROUP(3, 1, BW_20),
> + MCS_GROUP(4, 1, BW_20),
> +
> + MCS_GROUP(1, 0, BW_40),
> + MCS_GROUP(2, 0, BW_40),
> + MCS_GROUP(3, 0, BW_40),
> + MCS_GROUP(4, 0, BW_40),
> +
> + MCS_GROUP(1, 1, BW_40),
> + MCS_GROUP(2, 1, BW_40),
> + MCS_GROUP(3, 1, BW_40),
> + MCS_GROUP(4, 1, BW_40),
> +
> + VHT_GROUP(1, 0, BW_20),
> + VHT_GROUP(2, 0, BW_20),
> + VHT_GROUP(3, 0, BW_20),
> + VHT_GROUP(4, 0, BW_20),
> +
> + VHT_GROUP(1, 1, BW_20),
> + VHT_GROUP(2, 1, BW_20),
> + VHT_GROUP(3, 1, BW_20),
> + VHT_GROUP(4, 1, BW_20),
> +
> + VHT_GROUP(1, 0, BW_40),
> + VHT_GROUP(2, 0, BW_40),
> + VHT_GROUP(3, 0, BW_40),
> + VHT_GROUP(4, 0, BW_40),
> +
> + VHT_GROUP(1, 1, BW_40),
> + VHT_GROUP(2, 1, BW_40),
> + VHT_GROUP(3, 1, BW_40),
> + VHT_GROUP(4, 1, BW_40),
> +
> + VHT_GROUP(1, 0, BW_80),
> + VHT_GROUP(2, 0, BW_80),
> + VHT_GROUP(3, 0, BW_80),
> + VHT_GROUP(4, 0, BW_80),
> +
> + VHT_GROUP(1, 1, BW_80),
> + VHT_GROUP(2, 1, BW_80),
> + VHT_GROUP(3, 1, BW_80),
> + VHT_GROUP(4, 1, BW_80),
> +};
> +
> +static u32
> +mt76_calc_legacy_rate_duration(const struct ieee80211_rate *rate, bool short_pre,
> + int len)
> +{
> + u32 duration;
> +
> + switch (rate->hw_value >> 8) {
> + case MT_PHY_TYPE_CCK:
> + duration = 144 + 48; /* preamble + PLCP */
> + if (short_pre)
> + duration >>= 1;
> +
> + duration += 10; /* SIFS */
> + break;
> + case MT_PHY_TYPE_OFDM:
> + duration = 20 + 16; /* premable + SIFS */
> + break;
> + default:
> + WARN_ON_ONCE(1);
> + return 0;
> + }
> +
> + len <<= 3;
> + duration += (len * 10) / rate->bitrate;
> +
> + return duration;
> +}
> +
> +u32 mt76_calc_rx_airtime(struct mt76_dev *dev, struct mt76_rx_status *status,
> + int len)
> +{
> + struct ieee80211_supported_band *sband;
> + const struct ieee80211_rate *rate;
> + bool sgi = status->enc_flags & RX_ENC_FLAG_SHORT_GI;
> + bool sp = status->enc_flags & RX_ENC_FLAG_SHORTPRE;
> + int bw, streams;
> + u32 duration;
> + int group, idx;
> +
> + switch (status->bw) {
> + case RATE_INFO_BW_20:
> + bw = BW_20;
> + break;
> + case RATE_INFO_BW_40:
> + bw = BW_40;
> + break;
> + case RATE_INFO_BW_80:
> + bw = BW_80;
> + break;
> + default:
> + WARN_ON_ONCE(1);
> + return 0;
> + }
> +
> + switch (status->encoding) {
> + case RX_ENC_LEGACY:
> + if (WARN_ON_ONCE(status->band > NL80211_BAND_5GHZ))
> + return 0;
> +
> + sband = dev->hw->wiphy->bands[status->band];
> + if (!sband || status->rate_idx > sband->n_bitrates)
> + return 0;
> +
> + rate = &sband->bitrates[status->rate_idx];
> +
> + return mt76_calc_legacy_rate_duration(rate, sp, len);
> + case RX_ENC_VHT:
> + streams = status->nss;
> + idx = status->rate_idx;
> + group = VHT_GROUP_IDX(streams, sgi, bw);
> + break;
> + case RX_ENC_HT:
> + streams = ((status->rate_idx >> 3) & 3) + 1;
> + idx = status->rate_idx & 7;
> + group = HT_GROUP_IDX(streams, sgi, bw);
> + break;
> + default:
> + WARN_ON_ONCE(1);
> + return 0;
> + }
> +
> + if (WARN_ON_ONCE(streams > 4))
> + return 0;
> +
> + duration = airtime_mcs_groups[group].duration[idx];
> + duration <<= airtime_mcs_groups[group].shift;
> + duration *= len;
> + duration /= AVG_PKT_SIZE;
> + duration /= 1024;
On an earlier patch of mine you expressed concern over divisions in the
fast path. Does this mean this is no longer a concern? Or is the
compiler doing fancy things with the constant division here? :)
-Toke
next prev parent reply other threads:[~2019-09-27 8:36 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-26 17:47 [PATCH 01/15] mt76: mt7603: remove q_rx field from struct mt7603_dev Felix Fietkau
2019-09-26 17:47 ` [PATCH 02/15] mt76: report rx a-mpdu subframe status Felix Fietkau
2019-09-26 17:47 ` [PATCH 03/15] mt76: rename mt76_driver_ops txwi_flags to drv_flags and include tx aligned4 Felix Fietkau
2019-09-26 17:47 ` [PATCH 04/15] mt76: store current channel survey_state in struct mt76_dev Felix Fietkau
2019-09-26 17:47 ` [PATCH 05/15] mt76: track rx airtime for airtime fairness and survey Felix Fietkau
2019-09-27 8:35 ` Toke Høiland-Jørgensen [this message]
2019-09-27 8:46 ` Felix Fietkau
2019-09-27 9:04 ` Toke Høiland-Jørgensen
2019-09-26 17:47 ` [PATCH 06/15] mt76: mt7603: track tx " Felix Fietkau
2019-09-26 17:47 ` [PATCH 07/15] mt76: mt7603: switch to a different counter for survey busy time Felix Fietkau
2019-09-26 17:47 ` [PATCH 08/15] mt76: unify channel survey update code Felix Fietkau
2019-09-26 17:47 ` [PATCH 09/15] mt76: mt76x02: move MT_CH_TIME_CFG init to mt76x02_mac_cc_reset Felix Fietkau
2019-09-26 17:47 ` [PATCH 10/15] mt76: mt76x02: track approximate tx airtime for airtime fairness and survey Felix Fietkau
2019-09-27 7:45 ` Toke Høiland-Jørgensen
2019-09-27 8:11 ` Felix Fietkau
2019-09-27 8:37 ` Toke Høiland-Jørgensen
2019-09-27 8:47 ` Felix Fietkau
2019-09-27 9:07 ` Toke Høiland-Jørgensen
2019-09-27 9:17 ` Felix Fietkau
2019-09-28 10:31 ` Toke Høiland-Jørgensen
2019-09-26 17:47 ` [PATCH 11/15] mt76: mt7615: report tx_time, bss_rx and busy time to mac80211 Felix Fietkau
2019-09-26 17:47 ` [PATCH 12/15] mt76: mt7615: fix survey channel busy time Felix Fietkau
2019-09-26 17:47 ` [PATCH 13/15] mt76: mt7615: introduce mt7615_mac_wtbl_update routine Felix Fietkau
2019-09-26 17:47 ` [PATCH 14/15] mt76: mt7615: track tx/rx airtime for airtime fairness Felix Fietkau
2019-09-26 17:47 ` [PATCH 15/15] mt76: enable " Felix Fietkau
2019-09-27 7:46 ` Toke Høiland-Jørgensen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87v9teyw40.fsf@toke.dk \
--to=toke@redhat.com \
--cc=linux-wireless@vger.kernel.org \
--cc=nbd@nbd.name \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).