From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7BF71CA9EAC for ; Sat, 19 Oct 2019 11:37:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3C192222C2 for ; Sat, 19 Oct 2019 11:37:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="GWFYCsbJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726263AbfJSLhZ (ORCPT ); Sat, 19 Oct 2019 07:37:25 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:30868 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725912AbfJSLhY (ORCPT ); Sat, 19 Oct 2019 07:37:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571485042; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=037kYcrwRSTSMLRfx4CfzNcNZlFM0quGkGQoN08cL8c=; b=GWFYCsbJUAwSwPwovvpcC7es1Sek6oegz+ruVaRzzkrXSO9050jMyWuAvQaYYvsGIBdn3g pT+JVQCLYh8P6MYHpvpmrLhLWajcdnAiaU4N1/GjqiVVWZCyTRSB3E2iDp98P1A5NledHR 2dYj9S6qNcYUB/N89kRsv8RTIi0JSXk= Received: from mail-lf1-f71.google.com (mail-lf1-f71.google.com [209.85.167.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-244-LsuxyQ--OQiMH5zt02wo0Q-1; Sat, 19 Oct 2019 07:37:20 -0400 Received: by mail-lf1-f71.google.com with SMTP id m24so1760989lfh.22 for ; Sat, 19 Oct 2019 04:37:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=8YRb2N6dvs3xtiXuol7/wWZTQ7TYCWwqAjekk5alzxE=; b=uU6/JVgYdoUY5ulA+n2bVIZTO2sn7oU8j8FSrA21TralLEDBDuLAVuOS4A1CchJeis x8WA4m2vfRHo9WHY10Px2IZg9x6CrClW0gudeSJMnhD9JCH2Ri4guNGfu+aviwdlI8c0 FFwdDYpluHl0GfsCBzO0bQwLzDfS5dDMXzYnfQrIWZmB/1sME4JH1Ouu45rtyBGbw9JQ Q08Pnhh94x/MfLnFE5jPkYakBZgeGDhG9wDvO9+YRA1yZMUV8wCfBy7LUrm80kfUPn4M ZFuyOQny6NmaPOD4DTsv2GiotiFHY+5F+0PS6oeNc0ah7xNS4Nu8XDOAl/YvACEapIfG Gt2w== X-Gm-Message-State: APjAAAWNOFWvT6bsvm9LmXkxfxFCAhmtC3f8yGSu6p9U7EWMBsAZHHuV A2RN1SmO6OM9xPqmDIF0epxxKqc1WdIZqYs4FD2nA7SNdS9v77mBBDMAlpo3DFxtzVj8+86rX0H uwe16XF20njiXmGZV2YkIUMgtSRY= X-Received: by 2002:a05:6512:71:: with SMTP id i17mr8732633lfo.68.1571485038572; Sat, 19 Oct 2019 04:37:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqx5Sb37FfZdcXLsWgNLkG3Qp9yoKg+1KpKvOrzk68btQ0fb7apBhu+aAD3ATqBsh9D3ijUO8g== X-Received: by 2002:a05:6512:71:: with SMTP id i17mr8732613lfo.68.1571485038103; Sat, 19 Oct 2019 04:37:18 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk (borgediget.toke.dk. [85.204.121.218]) by smtp.gmail.com with ESMTPSA id d24sm269009lfl.65.2019.10.19.04.37.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 19 Oct 2019 04:37:17 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 800331804C8; Sat, 19 Oct 2019 13:37:16 +0200 (CEST) Subject: [PATCH v4 2/4] mac80211: Import airtime calculation code from mt76 From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Johannes Berg Cc: linux-wireless@vger.kernel.org, make-wifi-fast@lists.bufferbloat.net, ath10k@lists.infradead.org, John Crispin , Lorenzo Bianconi , Felix Fietkau , Kan Yan , Rajkumar Manoharan , Kevin Hayes Date: Sat, 19 Oct 2019 13:37:16 +0200 Message-ID: <157148503639.2989444.8337290298332344733.stgit@toke.dk> In-Reply-To: <157148503415.2989444.7391437309981941226.stgit@toke.dk> References: <157148503415.2989444.7391437309981941226.stgit@toke.dk> User-Agent: StGit/0.20 MIME-Version: 1.0 X-MC-Unique: LsuxyQ--OQiMH5zt02wo0Q-1 X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Toke H=C3=B8iland-J=C3=B8rgensen Felix recently added code to calculate airtime of packets to the mt76 driver. Import this into mac80211 so we can use it for airtime queue limit calculations later. The airtime.c file is copied verbatim from the mt76 driver, and adjusted to use mac80211 data structures instead (which is fairly straight forward). The per-rate TX rate calculation is split out to its own function (ieee80211_calc_tx_airtime_rate()) so it can be used directly for the AQL calculations added in a subsequent patch. The only thing that it was not possible to port directly was the bit that read the internal driver flags of struct ieee80211_rate to determine whether a rate is using CCK or OFDM encoding. Instead, just look at the rate index, since at least mt76 and ath10k both seem to have the same number of CCK rates (4) in their tables. Signed-off-by: Toke H=C3=B8iland-J=C3=B8rgensen --- include/net/mac80211.h | 14 ++ net/mac80211/Makefile | 3=20 net/mac80211/airtime.c | 377 ++++++++++++++++++++++++++++++++++++++++= ++++ net/mac80211/ieee80211_i.h | 4=20 4 files changed, 397 insertions(+), 1 deletion(-) create mode 100644 net/mac80211/airtime.c diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 4288ace72c2b..f058386e3fef 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -6424,4 +6424,18 @@ void ieee80211_nan_func_match(struct ieee80211_vif *= vif, =09=09=09 struct cfg80211_nan_match_params *match, =09=09=09 gfp_t gfp); =20 +/** + * ieee80211_calc_tx_airtime - calculate estimated transmission airtime. + * + * This function calculates the estimated airtime usage of a frame based o= n the + * rate information in the TX info struct and the frame length. + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @info: &struct ieee80211_tx_info of the frame. + * @len: frame length in bytes + */ +u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw, +=09=09=09 struct ieee80211_tx_info *info, +=09=09=09 int len); + #endif /* MAC80211_H */ diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 4f03ebe732fa..6cbb1286d6c0 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -32,7 +32,8 @@ mac80211-y :=3D \ =09chan.o \ =09trace.o mlme.o \ =09tdls.o \ -=09ocb.o +=09ocb.o \ +=09airtime.o =20 mac80211-$(CONFIG_MAC80211_LEDS) +=3D led.o mac80211-$(CONFIG_MAC80211_DEBUGFS) +=3D \ diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c new file mode 100644 index 000000000000..c8d0cee61366 --- /dev/null +++ b/net/mac80211/airtime.c @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: ISC +/* + * Copyright (C) 2019 Felix Fietkau + */ + +#include +#include "ieee80211_i.h" +#include "sta_info.h" + +#define AVG_PKT_SIZE=091024 + +/* 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)=09=09=09=09=09\ +=09(sgi ?=09=09=09=09=09=09=09=09\ +=09 ((syms) * 18 * 1024 + 4 * 1024) / 5 :=09/* syms * 3.6 us */=09\ +=09 ((syms) * 1024) << 2=09=09=09/* syms * 4 us */=09\ +=09) + +/* Transmit duration for the raw data part of an average sized packet */ +#define MCS_DURATION(streams, sgi, bps) \ +=09MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) + +#define BW_20=09=09=090 +#define BW_40=09=09=091 +#define BW_80=09=09=092 + +/* + * Define group sort order: HT40 -> SGI -> #streams + */ +#define IEEE80211_MAX_STREAMS=09=094 +#define IEEE80211_HT_STREAM_GROUPS=094 /* BW(=3D2) * SGI(=3D2) */ +#define IEEE80211_VHT_STREAM_GROUPS=096 /* BW(=3D3) * SGI(=3D2) */ + +#define IEEE80211_HT_GROUPS_NB=09(IEEE80211_MAX_STREAMS *=09\ +=09=09=09=09 IEEE80211_HT_STREAM_GROUPS) +#define IEEE80211_VHT_GROUPS_NB=09(IEEE80211_MAX_STREAMS *=09\ +=09=09=09=09=09 IEEE80211_VHT_STREAM_GROUPS) +#define IEEE80211_GROUPS_NB=09(IEEE80211_HT_GROUPS_NB +=09\ +=09=09=09=09 IEEE80211_VHT_GROUPS_NB) + +#define IEEE80211_HT_GROUP_0=090 +#define IEEE80211_VHT_GROUP_0=09(IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUP= S_NB) + +#define MCS_GROUP_RATES=09=0910 +#define CCK_NUM_RATES=09=09=094 + +#define HT_GROUP_IDX(_streams, _sgi, _ht40)=09\ +=09IEEE80211_HT_GROUP_0 +=09=09=09\ +=09IEEE80211_MAX_STREAMS * 2 * _ht40 +=09\ +=09IEEE80211_MAX_STREAMS * _sgi +=09=09\ +=09_streams - 1 + +#define _MAX(a, b) (((a)>(b))?(a):(b)) + +#define GROUP_SHIFT(duration)=09=09=09=09=09=09\ +=09_MAX(0, 16 - __builtin_clz(duration)) + +/* MCS rate information for an MCS group */ +#define __MCS_GROUP(_streams, _sgi, _ht40, _s)=09=09=09=09\ +=09[HT_GROUP_IDX(_streams, _sgi, _ht40)] =3D {=09=09=09\ +=09.shift =3D _s,=09=09=09=09=09=09=09\ +=09.duration =3D {=09=09=09=09=09=09=09\ +=09=09MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s=09\ +=09}=09=09=09=09=09=09=09=09\ +} + +#define MCS_GROUP_SHIFT(_streams, _sgi, _ht40)=09=09=09=09\ +=09GROUP_SHIFT(MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26)) + +#define MCS_GROUP(_streams, _sgi, _ht40)=09=09=09=09\ +=09__MCS_GROUP(_streams, _sgi, _ht40,=09=09=09=09\ +=09=09 MCS_GROUP_SHIFT(_streams, _sgi, _ht40)) + +#define VHT_GROUP_IDX(_streams, _sgi, _bw)=09=09=09=09\ +=09(IEEE80211_VHT_GROUP_0 +=09=09=09=09=09=09\ +=09 IEEE80211_MAX_STREAMS * 2 * (_bw) +=09=09=09=09\ +=09 IEEE80211_MAX_STREAMS * (_sgi) +=09=09=09=09\ +=09 (_streams) - 1) + +#define BW2VBPS(_bw, r3, r2, r1)=09=09=09=09=09\ +=09(_bw =3D=3D BW_80 ? r3 : _bw =3D=3D BW_40 ? r2 : r1) + +#define __VHT_GROUP(_streams, _sgi, _bw, _s)=09=09=09=09\ +=09[VHT_GROUP_IDX(_streams, _sgi, _bw)] =3D {=09=09=09\ +=09.shift =3D _s,=09=09=09=09=09=09=09\ +=09.duration =3D {=09=09=09=09=09=09=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 117, 54, 26)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 234, 108, 52)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 351, 162, 78)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 468, 216, 104)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 702, 324, 156)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 936, 432, 208)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 1053, 486, 234)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 1170, 540, 260)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 1404, 648, 312)) >> _s,=09\ +=09=09MCS_DURATION(_streams, _sgi,=09=09=09=09\ +=09=09=09 BW2VBPS(_bw, 1560, 720, 346)) >> _s=09\ +=09}=09=09=09=09=09=09=09=09\ +} + +#define VHT_GROUP_SHIFT(_streams, _sgi, _bw)=09=09=09=09\ +=09GROUP_SHIFT(MCS_DURATION(_streams, _sgi,=09=09=09\ +=09=09=09=09 BW2VBPS(_bw, 117, 54, 26))) + +#define VHT_GROUP(_streams, _sgi, _bw)=09=09=09=09=09\ +=09__VHT_GROUP(_streams, _sgi, _bw,=09=09=09=09\ +=09=09 VHT_GROUP_SHIFT(_streams, _sgi, _bw)) + +struct mcs_group { +=09u8 shift; +=09u16 duration[MCS_GROUP_RATES]; +}; + +static const struct mcs_group airtime_mcs_groups[] =3D { +=09MCS_GROUP(1, 0, BW_20), +=09MCS_GROUP(2, 0, BW_20), +=09MCS_GROUP(3, 0, BW_20), +=09MCS_GROUP(4, 0, BW_20), + +=09MCS_GROUP(1, 1, BW_20), +=09MCS_GROUP(2, 1, BW_20), +=09MCS_GROUP(3, 1, BW_20), +=09MCS_GROUP(4, 1, BW_20), + +=09MCS_GROUP(1, 0, BW_40), +=09MCS_GROUP(2, 0, BW_40), +=09MCS_GROUP(3, 0, BW_40), +=09MCS_GROUP(4, 0, BW_40), + +=09MCS_GROUP(1, 1, BW_40), +=09MCS_GROUP(2, 1, BW_40), +=09MCS_GROUP(3, 1, BW_40), +=09MCS_GROUP(4, 1, BW_40), + +=09VHT_GROUP(1, 0, BW_20), +=09VHT_GROUP(2, 0, BW_20), +=09VHT_GROUP(3, 0, BW_20), +=09VHT_GROUP(4, 0, BW_20), + +=09VHT_GROUP(1, 1, BW_20), +=09VHT_GROUP(2, 1, BW_20), +=09VHT_GROUP(3, 1, BW_20), +=09VHT_GROUP(4, 1, BW_20), + +=09VHT_GROUP(1, 0, BW_40), +=09VHT_GROUP(2, 0, BW_40), +=09VHT_GROUP(3, 0, BW_40), +=09VHT_GROUP(4, 0, BW_40), + +=09VHT_GROUP(1, 1, BW_40), +=09VHT_GROUP(2, 1, BW_40), +=09VHT_GROUP(3, 1, BW_40), +=09VHT_GROUP(4, 1, BW_40), + +=09VHT_GROUP(1, 0, BW_80), +=09VHT_GROUP(2, 0, BW_80), +=09VHT_GROUP(3, 0, BW_80), +=09VHT_GROUP(4, 0, BW_80), + +=09VHT_GROUP(1, 1, BW_80), +=09VHT_GROUP(2, 1, BW_80), +=09VHT_GROUP(3, 1, BW_80), +=09VHT_GROUP(4, 1, BW_80), +}; + +static u32 +ieee80211_calc_legacy_rate_duration(const struct ieee80211_rate *rate, +=09=09=09=09 bool short_pre, bool cck, +=09=09=09=09 int len) +{ +=09u32 duration; + +=09if (cck) { +=09=09duration =3D 144 + 48; /* preamble + PLCP */ +=09=09if (short_pre) +=09=09=09duration >>=3D 1; + +=09=09duration +=3D 10; /* SIFS */ +=09} else { +=09=09duration =3D 20 + 16; /* premable + SIFS */ +=09} + +=09len <<=3D 3; +=09duration +=3D (len * 10) / rate->bitrate; + +=09return duration; +} + +u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw, +=09=09=09 struct ieee80211_rx_status *status, +=09=09=09 int len) +{ +=09struct ieee80211_supported_band *sband; +=09const struct ieee80211_rate *rate; +=09bool sgi =3D status->enc_flags & RX_ENC_FLAG_SHORT_GI; +=09bool sp =3D status->enc_flags & RX_ENC_FLAG_SHORTPRE; +=09int bw, streams; +=09u32 duration; +=09int group, idx; +=09bool cck; + +=09switch (status->bw) { +=09case RATE_INFO_BW_20: +=09=09bw =3D BW_20; +=09=09break; +=09case RATE_INFO_BW_40: +=09=09bw =3D BW_40; +=09=09break; +=09case RATE_INFO_BW_80: +=09=09bw =3D BW_80; +=09=09break; +=09default: +=09=09WARN_ON_ONCE(1); +=09=09return 0; +=09} + +=09switch (status->encoding) { +=09case RX_ENC_LEGACY: +=09=09if (WARN_ON_ONCE(status->band > NL80211_BAND_5GHZ)) +=09=09=09return 0; + +=09=09sband =3D hw->wiphy->bands[status->band]; +=09=09if (!sband || status->rate_idx > sband->n_bitrates) +=09=09=09return 0; + +=09=09rate =3D &sband->bitrates[status->rate_idx]; +=09=09cck =3D (status->rate_idx < CCK_NUM_RATES); + +=09=09return ieee80211_calc_legacy_rate_duration(rate, sp, cck, len); + +=09case RX_ENC_VHT: +=09=09streams =3D status->nss; +=09=09idx =3D status->rate_idx; +=09=09group =3D VHT_GROUP_IDX(streams, sgi, bw); +=09=09break; +=09case RX_ENC_HT: +=09=09streams =3D ((status->rate_idx >> 3) & 3) + 1; +=09=09idx =3D status->rate_idx & 7; +=09=09group =3D HT_GROUP_IDX(streams, sgi, bw); +=09=09break; +=09default: +=09=09WARN_ON_ONCE(1); +=09=09return 0; +=09} + +=09if (WARN_ON_ONCE(streams > 4)) +=09=09return 0; + +=09duration =3D airtime_mcs_groups[group].duration[idx]; +=09duration <<=3D airtime_mcs_groups[group].shift; +=09duration *=3D len; +=09duration /=3D AVG_PKT_SIZE; +=09duration /=3D 1024; + +=09duration +=3D 36 + (streams << 2); + +=09return duration; +} + +u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw, +=09=09=09=09 struct ieee80211_tx_rate *rate, +=09=09=09=09 u8 band, int len) +{ +=09struct ieee80211_rx_status stat =3D { +=09=09.band =3D band, +=09}; + +=09if (rate->idx < 0 || !rate->count) +=09=09return 0; + +=09if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) +=09=09stat.bw =3D RATE_INFO_BW_80; +=09else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) +=09=09stat.bw =3D RATE_INFO_BW_40; +=09else +=09=09stat.bw =3D RATE_INFO_BW_20; + +=09stat.enc_flags =3D 0; +=09if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) +=09=09stat.enc_flags |=3D RX_ENC_FLAG_SHORTPRE; +=09if (rate->flags & IEEE80211_TX_RC_SHORT_GI) +=09=09stat.enc_flags |=3D RX_ENC_FLAG_SHORT_GI; + +=09stat.rate_idx =3D rate->idx; +=09if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { +=09=09stat.encoding =3D RX_ENC_VHT; +=09=09stat.rate_idx =3D ieee80211_rate_get_vht_mcs(rate); +=09=09stat.nss =3D ieee80211_rate_get_vht_nss(rate); +=09} else if (rate->flags & IEEE80211_TX_RC_MCS) { +=09=09stat.encoding =3D RX_ENC_HT; +=09} else { +=09=09stat.encoding =3D RX_ENC_LEGACY; +=09} + +=09return ieee80211_calc_rx_airtime(hw, &stat, len); +} + +u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw, +=09=09=09 struct ieee80211_tx_info *info, +=09=09=09 int len) +{ +=09u32 duration =3D 0; +=09int i; + +=09for (i =3D 0; i < ARRAY_SIZE(info->status.rates); i++) { +=09=09struct ieee80211_tx_rate *rate =3D &info->status.rates[i]; +=09=09u32 cur_duration; + +=09=09cur_duration =3D ieee80211_calc_tx_airtime_rate(hw, rate, +=09=09=09=09=09=09=09 info->band, len); +=09=09if (!cur_duration) +=09=09=09break; + +=09=09duration +=3D cur_duration * rate->count; +=09} + +=09return duration; +} +EXPORT_SYMBOL_GPL(ieee80211_calc_tx_airtime); + + +u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, +=09=09=09=09 struct ieee80211_vif *vif, +=09=09=09=09 struct ieee80211_sta *pubsta, +=09=09=09=09 int len) +{ +=09struct ieee80211_supported_band *sband; +=09struct ieee80211_chanctx_conf *conf; +=09struct ieee80211_rate *rate; +=09struct sta_info *sta; +=09u8 band =3D 0; + +=09len +=3D 38; /* Ethernet header length */ + +=09conf =3D rcu_dereference(vif->chanctx_conf); +=09if (conf) +=09=09band =3D conf->def.chan->band; + +=09if (pubsta) { +=09=09sta =3D container_of(pubsta, struct sta_info, sta); +=09=09return ieee80211_calc_tx_airtime_rate(hw, &sta->tx_stats.last_rate, +=09=09=09=09=09=09 band, len); +=09} + +=09if (!conf) +=09=09return 0; + +=09/* No station to get latest rate from, so calculate the +=09 * worst-case duration for the lowest rate. +=09 */ +=09sband =3D hw->wiphy->bands[band]; +=09rate =3D &sband->bitrates[0]; + +=09return ieee80211_calc_legacy_rate_duration(rate, false, true, len); +} diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 05406e9c05b3..225ea4e3cd76 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2249,6 +2249,10 @@ const char *ieee80211_get_reason_code_string(u16 rea= son_code); =20 extern const struct ethtool_ops ieee80211_ethtool_ops; =20 +u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, +=09=09=09=09 struct ieee80211_vif *vif, +=09=09=09=09 struct ieee80211_sta *pubsta, +=09=09=09=09 int len); #ifdef CONFIG_MAC80211_NOINLINE #define debug_noinline noinline #else From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from us-smtp-2.mimecast.com ([207.211.31.81] helo=us-smtp-delivery-1.mimecast.com) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iLn2z-0003tW-CB for ath10k@lists.infradead.org; Sat, 19 Oct 2019 11:37:27 +0000 Received: by mail-lf1-f70.google.com with SMTP id c13so1751102lfk.23 for ; Sat, 19 Oct 2019 04:37:20 -0700 (PDT) Subject: [PATCH v4 2/4] mac80211: Import airtime calculation code from mt76 From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= Date: Sat, 19 Oct 2019 13:37:16 +0200 Message-ID: <157148503639.2989444.8337290298332344733.stgit@toke.dk> In-Reply-To: <157148503415.2989444.7391437309981941226.stgit@toke.dk> References: <157148503415.2989444.7391437309981941226.stgit@toke.dk> MIME-Version: 1.0 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "ath10k" Errors-To: ath10k-bounces+kvalo=adurom.com@lists.infradead.org To: Johannes Berg Cc: Kan Yan , Rajkumar Manoharan , Kevin Hayes , make-wifi-fast@lists.bufferbloat.net, linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, John Crispin , Lorenzo Bianconi , Felix Fietkau RnJvbTogVG9rZSBIw7hpbGFuZC1Kw7hyZ2Vuc2VuIDx0b2tlQHJlZGhhdC5jb20+CgpGZWxpeCBy ZWNlbnRseSBhZGRlZCBjb2RlIHRvIGNhbGN1bGF0ZSBhaXJ0aW1lIG9mIHBhY2tldHMgdG8gdGhl IG10NzYKZHJpdmVyLiBJbXBvcnQgdGhpcyBpbnRvIG1hYzgwMjExIHNvIHdlIGNhbiB1c2UgaXQg Zm9yIGFpcnRpbWUgcXVldWUgbGltaXQKY2FsY3VsYXRpb25zIGxhdGVyLgoKVGhlIGFpcnRpbWUu YyBmaWxlIGlzIGNvcGllZCB2ZXJiYXRpbSBmcm9tIHRoZSBtdDc2IGRyaXZlciwgYW5kIGFkanVz dGVkIHRvCnVzZSBtYWM4MDIxMSBkYXRhIHN0cnVjdHVyZXMgaW5zdGVhZCAod2hpY2ggaXMgZmFp cmx5IHN0cmFpZ2h0IGZvcndhcmQpLgpUaGUgcGVyLXJhdGUgVFggcmF0ZSBjYWxjdWxhdGlvbiBp cyBzcGxpdCBvdXQgdG8gaXRzIG93bgpmdW5jdGlvbiAoaWVlZTgwMjExX2NhbGNfdHhfYWlydGlt ZV9yYXRlKCkpIHNvIGl0IGNhbiBiZSB1c2VkIGRpcmVjdGx5IGZvcgp0aGUgQVFMIGNhbGN1bGF0 aW9ucyBhZGRlZCBpbiBhIHN1YnNlcXVlbnQgcGF0Y2guCgpUaGUgb25seSB0aGluZyB0aGF0IGl0 IHdhcyBub3QgcG9zc2libGUgdG8gcG9ydCBkaXJlY3RseSB3YXMgdGhlIGJpdCB0aGF0CnJlYWQg dGhlIGludGVybmFsIGRyaXZlciBmbGFncyBvZiBzdHJ1Y3QgaWVlZTgwMjExX3JhdGUgdG8gZGV0 ZXJtaW5lCndoZXRoZXIgYSByYXRlIGlzIHVzaW5nIENDSyBvciBPRkRNIGVuY29kaW5nLiBJbnN0 ZWFkLCBqdXN0IGxvb2sgYXQgdGhlCnJhdGUgaW5kZXgsIHNpbmNlIGF0IGxlYXN0IG10NzYgYW5k IGF0aDEwayBib3RoIHNlZW0gdG8gaGF2ZSB0aGUgc2FtZQpudW1iZXIgb2YgQ0NLIHJhdGVzICg0 KSBpbiB0aGVpciB0YWJsZXMuCgpTaWduZWQtb2ZmLWJ5OiBUb2tlIEjDuGlsYW5kLUrDuHJnZW5z ZW4gPHRva2VAcmVkaGF0LmNvbT4KLS0tCiBpbmNsdWRlL25ldC9tYWM4MDIxMS5oICAgICB8ICAg MTQgKysKIG5ldC9tYWM4MDIxMS9NYWtlZmlsZSAgICAgIHwgICAgMyAKIG5ldC9tYWM4MDIxMS9h aXJ0aW1lLmMgICAgIHwgIDM3NyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKwogbmV0L21hYzgwMjExL2llZWU4MDIxMV9pLmggfCAgICA0IAogNCBmaWxlcyBjaGFu Z2VkLCAzOTcgaW5zZXJ0aW9ucygrKSwgMSBkZWxldGlvbigtKQogY3JlYXRlIG1vZGUgMTAwNjQ0 IG5ldC9tYWM4MDIxMS9haXJ0aW1lLmMKCmRpZmYgLS1naXQgYS9pbmNsdWRlL25ldC9tYWM4MDIx MS5oIGIvaW5jbHVkZS9uZXQvbWFjODAyMTEuaAppbmRleCA0Mjg4YWNlNzJjMmIuLmYwNTgzODZl M2ZlZiAxMDA2NDQKLS0tIGEvaW5jbHVkZS9uZXQvbWFjODAyMTEuaAorKysgYi9pbmNsdWRlL25l dC9tYWM4MDIxMS5oCkBAIC02NDI0LDQgKzY0MjQsMTggQEAgdm9pZCBpZWVlODAyMTFfbmFuX2Z1 bmNfbWF0Y2goc3RydWN0IGllZWU4MDIxMV92aWYgKnZpZiwKIAkJCSAgICAgIHN0cnVjdCBjZmc4 MDIxMV9uYW5fbWF0Y2hfcGFyYW1zICptYXRjaCwKIAkJCSAgICAgIGdmcF90IGdmcCk7CiAKKy8q KgorICogaWVlZTgwMjExX2NhbGNfdHhfYWlydGltZSAtIGNhbGN1bGF0ZSBlc3RpbWF0ZWQgdHJh bnNtaXNzaW9uIGFpcnRpbWUuCisgKgorICogVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIHRoZSBl c3RpbWF0ZWQgYWlydGltZSB1c2FnZSBvZiBhIGZyYW1lIGJhc2VkIG9uIHRoZQorICogcmF0ZSBp bmZvcm1hdGlvbiBpbiB0aGUgVFggaW5mbyBzdHJ1Y3QgYW5kIHRoZSBmcmFtZSBsZW5ndGguCisg KgorICogQGh3OiBwb2ludGVyIGFzIG9idGFpbmVkIGZyb20gaWVlZTgwMjExX2FsbG9jX2h3KCkK KyAqIEBpbmZvOiAmc3RydWN0IGllZWU4MDIxMV90eF9pbmZvIG9mIHRoZSBmcmFtZS4KKyAqIEBs ZW46IGZyYW1lIGxlbmd0aCBpbiBieXRlcworICovCit1MzIgaWVlZTgwMjExX2NhbGNfdHhfYWly dGltZShzdHJ1Y3QgaWVlZTgwMjExX2h3ICpodywKKwkJCSAgICAgIHN0cnVjdCBpZWVlODAyMTFf dHhfaW5mbyAqaW5mbywKKwkJCSAgICAgIGludCBsZW4pOworCiAjZW5kaWYgLyogTUFDODAyMTFf SCAqLwpkaWZmIC0tZ2l0IGEvbmV0L21hYzgwMjExL01ha2VmaWxlIGIvbmV0L21hYzgwMjExL01h a2VmaWxlCmluZGV4IDRmMDNlYmU3MzJmYS4uNmNiYjEyODZkNmMwIDEwMDY0NAotLS0gYS9uZXQv bWFjODAyMTEvTWFrZWZpbGUKKysrIGIvbmV0L21hYzgwMjExL01ha2VmaWxlCkBAIC0zMiw3ICsz Miw4IEBAIG1hYzgwMjExLXkgOj0gXAogCWNoYW4ubyBcCiAJdHJhY2UubyBtbG1lLm8gXAogCXRk bHMubyBcCi0Jb2NiLm8KKwlvY2IubyBcCisJYWlydGltZS5vCiAKIG1hYzgwMjExLSQoQ09ORklH X01BQzgwMjExX0xFRFMpICs9IGxlZC5vCiBtYWM4MDIxMS0kKENPTkZJR19NQUM4MDIxMV9ERUJV R0ZTKSArPSBcCmRpZmYgLS1naXQgYS9uZXQvbWFjODAyMTEvYWlydGltZS5jIGIvbmV0L21hYzgw MjExL2FpcnRpbWUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLmM4 ZDBjZWU2MTM2NgotLS0gL2Rldi9udWxsCisrKyBiL25ldC9tYWM4MDIxMS9haXJ0aW1lLmMKQEAg LTAsMCArMSwzNzcgQEAKKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBJU0MKKy8qCisgKiBD b3B5cmlnaHQgKEMpIDIwMTkgRmVsaXggRmlldGthdSA8bmJkQG5iZC5uYW1lPgorICovCisKKyNp bmNsdWRlIDxuZXQvbWFjODAyMTEuaD4KKyNpbmNsdWRlICJpZWVlODAyMTFfaS5oIgorI2luY2x1 ZGUgInN0YV9pbmZvLmgiCisKKyNkZWZpbmUgQVZHX1BLVF9TSVpFCTEwMjQKKworLyogTnVtYmVy IG9mIGJpdHMgZm9yIGFuIGF2ZXJhZ2Ugc2l6ZWQgcGFja2V0ICovCisjZGVmaW5lIE1DU19OQklU UyAoQVZHX1BLVF9TSVpFIDw8IDMpCisKKy8qIE51bWJlciBvZiBzeW1ib2xzIGZvciBhIHBhY2tl dCB3aXRoIChicHMpIGJpdHMgcGVyIHN5bWJvbCAqLworI2RlZmluZSBNQ1NfTlNZTVMoYnBzKSBE SVZfUk9VTkRfVVAoTUNTX05CSVRTLCAoYnBzKSkKKworLyogVHJhbnNtaXNzaW9uIHRpbWUgKDEw MjQgdXNlYykgZm9yIGEgcGFja2V0IGNvbnRhaW5pbmcgKHN5bXMpICogc3ltYm9scyAqLworI2Rl ZmluZSBNQ1NfU1lNQk9MX1RJTUUoc2dpLCBzeW1zKQkJCQkJXAorCShzZ2kgPwkJCQkJCQkJXAor CSAgKChzeW1zKSAqIDE4ICogMTAyNCArIDQgKiAxMDI0KSAvIDUgOgkvKiBzeW1zICogMy42IHVz ICovCVwKKwkgICgoc3ltcykgKiAxMDI0KSA8PCAyCQkJLyogc3ltcyAqIDQgdXMgKi8JXAorCSkK KworLyogVHJhbnNtaXQgZHVyYXRpb24gZm9yIHRoZSByYXcgZGF0YSBwYXJ0IG9mIGFuIGF2ZXJh Z2Ugc2l6ZWQgcGFja2V0ICovCisjZGVmaW5lIE1DU19EVVJBVElPTihzdHJlYW1zLCBzZ2ksIGJw cykgXAorCU1DU19TWU1CT0xfVElNRShzZ2ksIE1DU19OU1lNUygoc3RyZWFtcykgKiAoYnBzKSkp CisKKyNkZWZpbmUgQldfMjAJCQkwCisjZGVmaW5lIEJXXzQwCQkJMQorI2RlZmluZSBCV184MAkJ CTIKKworLyoKKyAqIERlZmluZSBncm91cCBzb3J0IG9yZGVyOiBIVDQwIC0+IFNHSSAtPiAjc3Ry ZWFtcworICovCisjZGVmaW5lIElFRUU4MDIxMV9NQVhfU1RSRUFNUwkJNAorI2RlZmluZSBJRUVF ODAyMTFfSFRfU1RSRUFNX0dST1VQUwk0IC8qIEJXKD0yKSAqIFNHSSg9MikgKi8KKyNkZWZpbmUg SUVFRTgwMjExX1ZIVF9TVFJFQU1fR1JPVVBTCTYgLyogQlcoPTMpICogU0dJKD0yKSAqLworCisj ZGVmaW5lIElFRUU4MDIxMV9IVF9HUk9VUFNfTkIJKElFRUU4MDIxMV9NQVhfU1RSRUFNUyAqCVwK KwkJCQkgSUVFRTgwMjExX0hUX1NUUkVBTV9HUk9VUFMpCisjZGVmaW5lIElFRUU4MDIxMV9WSFRf R1JPVVBTX05CCShJRUVFODAyMTFfTUFYX1NUUkVBTVMgKglcCisJCQkJCSBJRUVFODAyMTFfVkhU X1NUUkVBTV9HUk9VUFMpCisjZGVmaW5lIElFRUU4MDIxMV9HUk9VUFNfTkIJKElFRUU4MDIxMV9I VF9HUk9VUFNfTkIgKwlcCisJCQkJIElFRUU4MDIxMV9WSFRfR1JPVVBTX05CKQorCisjZGVmaW5l IElFRUU4MDIxMV9IVF9HUk9VUF8wCTAKKyNkZWZpbmUgSUVFRTgwMjExX1ZIVF9HUk9VUF8wCShJ RUVFODAyMTFfSFRfR1JPVVBfMCArIElFRUU4MDIxMV9IVF9HUk9VUFNfTkIpCisKKyNkZWZpbmUg TUNTX0dST1VQX1JBVEVTCQkxMAorI2RlZmluZSBDQ0tfTlVNX1JBVEVTCQkJNAorCisjZGVmaW5l IEhUX0dST1VQX0lEWChfc3RyZWFtcywgX3NnaSwgX2h0NDApCVwKKwlJRUVFODAyMTFfSFRfR1JP VVBfMCArCQkJXAorCUlFRUU4MDIxMV9NQVhfU1RSRUFNUyAqIDIgKiBfaHQ0MCArCVwKKwlJRUVF ODAyMTFfTUFYX1NUUkVBTVMgKiBfc2dpICsJCVwKKwlfc3RyZWFtcyAtIDEKKworI2RlZmluZSBf TUFYKGEsIGIpICgoKGEpPihiKSk/KGEpOihiKSkKKworI2RlZmluZSBHUk9VUF9TSElGVChkdXJh dGlvbikJCQkJCQlcCisJX01BWCgwLCAxNiAtIF9fYnVpbHRpbl9jbHooZHVyYXRpb24pKQorCisv KiBNQ1MgcmF0ZSBpbmZvcm1hdGlvbiBmb3IgYW4gTUNTIGdyb3VwICovCisjZGVmaW5lIF9fTUNT X0dST1VQKF9zdHJlYW1zLCBfc2dpLCBfaHQ0MCwgX3MpCQkJCVwKKwlbSFRfR1JPVVBfSURYKF9z dHJlYW1zLCBfc2dpLCBfaHQ0MCldID0gewkJCVwKKwkuc2hpZnQgPSBfcywJCQkJCQkJXAorCS5k dXJhdGlvbiA9IHsJCQkJCQkJXAorCQlNQ1NfRFVSQVRJT04oX3N0cmVhbXMsIF9zZ2ksIF9odDQw ID8gNTQgOiAyNikgPj4gX3MsCVwKKwkJTUNTX0RVUkFUSU9OKF9zdHJlYW1zLCBfc2dpLCBfaHQ0 MCA/IDEwOCA6IDUyKSA+PiBfcywJXAorCQlNQ1NfRFVSQVRJT04oX3N0cmVhbXMsIF9zZ2ksIF9o dDQwID8gMTYyIDogNzgpID4+IF9zLAlcCisJCU1DU19EVVJBVElPTihfc3RyZWFtcywgX3NnaSwg X2h0NDAgPyAyMTYgOiAxMDQpID4+IF9zLAlcCisJCU1DU19EVVJBVElPTihfc3RyZWFtcywgX3Nn aSwgX2h0NDAgPyAzMjQgOiAxNTYpID4+IF9zLAlcCisJCU1DU19EVVJBVElPTihfc3RyZWFtcywg X3NnaSwgX2h0NDAgPyA0MzIgOiAyMDgpID4+IF9zLAlcCisJCU1DU19EVVJBVElPTihfc3RyZWFt cywgX3NnaSwgX2h0NDAgPyA0ODYgOiAyMzQpID4+IF9zLAlcCisJCU1DU19EVVJBVElPTihfc3Ry ZWFtcywgX3NnaSwgX2h0NDAgPyA1NDAgOiAyNjApID4+IF9zCVwKKwl9CQkJCQkJCQlcCit9CisK KyNkZWZpbmUgTUNTX0dST1VQX1NISUZUKF9zdHJlYW1zLCBfc2dpLCBfaHQ0MCkJCQkJXAorCUdS T1VQX1NISUZUKE1DU19EVVJBVElPTihfc3RyZWFtcywgX3NnaSwgX2h0NDAgPyA1NCA6IDI2KSkK KworI2RlZmluZSBNQ1NfR1JPVVAoX3N0cmVhbXMsIF9zZ2ksIF9odDQwKQkJCQlcCisJX19NQ1Nf R1JPVVAoX3N0cmVhbXMsIF9zZ2ksIF9odDQwLAkJCQlcCisJCSAgICBNQ1NfR1JPVVBfU0hJRlQo X3N0cmVhbXMsIF9zZ2ksIF9odDQwKSkKKworI2RlZmluZSBWSFRfR1JPVVBfSURYKF9zdHJlYW1z LCBfc2dpLCBfYncpCQkJCVwKKwkoSUVFRTgwMjExX1ZIVF9HUk9VUF8wICsJCQkJCQlcCisJIElF RUU4MDIxMV9NQVhfU1RSRUFNUyAqIDIgKiAoX2J3KSArCQkJCVwKKwkgSUVFRTgwMjExX01BWF9T VFJFQU1TICogKF9zZ2kpICsJCQkJXAorCSAoX3N0cmVhbXMpIC0gMSkKKworI2RlZmluZSBCVzJW QlBTKF9idywgcjMsIHIyLCByMSkJCQkJCVwKKwkoX2J3ID09IEJXXzgwID8gcjMgOiBfYncgPT0g QldfNDAgPyByMiA6IHIxKQorCisjZGVmaW5lIF9fVkhUX0dST1VQKF9zdHJlYW1zLCBfc2dpLCBf YncsIF9zKQkJCQlcCisJW1ZIVF9HUk9VUF9JRFgoX3N0cmVhbXMsIF9zZ2ksIF9idyldID0gewkJ CVwKKwkuc2hpZnQgPSBfcywJCQkJCQkJXAorCS5kdXJhdGlvbiA9IHsJCQkJCQkJXAorCQlNQ1Nf RFVSQVRJT04oX3N0cmVhbXMsIF9zZ2ksCQkJCVwKKwkJCSAgICAgQlcyVkJQUyhfYncsICAxMTcs ICA1NCwgIDI2KSkgPj4gX3MsCVwKKwkJTUNTX0RVUkFUSU9OKF9zdHJlYW1zLCBfc2dpLAkJCQlc CisJCQkgICAgIEJXMlZCUFMoX2J3LCAgMjM0LCAxMDgsICA1MikpID4+IF9zLAlcCisJCU1DU19E VVJBVElPTihfc3RyZWFtcywgX3NnaSwJCQkJXAorCQkJICAgICBCVzJWQlBTKF9idywgIDM1MSwg MTYyLCAgNzgpKSA+PiBfcywJXAorCQlNQ1NfRFVSQVRJT04oX3N0cmVhbXMsIF9zZ2ksCQkJCVwK KwkJCSAgICAgQlcyVkJQUyhfYncsICA0NjgsIDIxNiwgMTA0KSkgPj4gX3MsCVwKKwkJTUNTX0RV UkFUSU9OKF9zdHJlYW1zLCBfc2dpLAkJCQlcCisJCQkgICAgIEJXMlZCUFMoX2J3LCAgNzAyLCAz MjQsIDE1NikpID4+IF9zLAlcCisJCU1DU19EVVJBVElPTihfc3RyZWFtcywgX3NnaSwJCQkJXAor CQkJICAgICBCVzJWQlBTKF9idywgIDkzNiwgNDMyLCAyMDgpKSA+PiBfcywJXAorCQlNQ1NfRFVS QVRJT04oX3N0cmVhbXMsIF9zZ2ksCQkJCVwKKwkJCSAgICAgQlcyVkJQUyhfYncsIDEwNTMsIDQ4 NiwgMjM0KSkgPj4gX3MsCVwKKwkJTUNTX0RVUkFUSU9OKF9zdHJlYW1zLCBfc2dpLAkJCQlcCisJ CQkgICAgIEJXMlZCUFMoX2J3LCAxMTcwLCA1NDAsIDI2MCkpID4+IF9zLAlcCisJCU1DU19EVVJB VElPTihfc3RyZWFtcywgX3NnaSwJCQkJXAorCQkJICAgICBCVzJWQlBTKF9idywgMTQwNCwgNjQ4 LCAzMTIpKSA+PiBfcywJXAorCQlNQ1NfRFVSQVRJT04oX3N0cmVhbXMsIF9zZ2ksCQkJCVwKKwkJ CSAgICAgQlcyVkJQUyhfYncsIDE1NjAsIDcyMCwgMzQ2KSkgPj4gX3MJXAorCX0JCQkJCQkJCVwK K30KKworI2RlZmluZSBWSFRfR1JPVVBfU0hJRlQoX3N0cmVhbXMsIF9zZ2ksIF9idykJCQkJXAor CUdST1VQX1NISUZUKE1DU19EVVJBVElPTihfc3RyZWFtcywgX3NnaSwJCQlcCisJCQkJIEJXMlZC UFMoX2J3LCAgMTE3LCAgNTQsICAyNikpKQorCisjZGVmaW5lIFZIVF9HUk9VUChfc3RyZWFtcywg X3NnaSwgX2J3KQkJCQkJXAorCV9fVkhUX0dST1VQKF9zdHJlYW1zLCBfc2dpLCBfYncsCQkJCVwK KwkJICAgIFZIVF9HUk9VUF9TSElGVChfc3RyZWFtcywgX3NnaSwgX2J3KSkKKworc3RydWN0IG1j c19ncm91cCB7CisJdTggc2hpZnQ7CisJdTE2IGR1cmF0aW9uW01DU19HUk9VUF9SQVRFU107Cit9 OworCitzdGF0aWMgY29uc3Qgc3RydWN0IG1jc19ncm91cCBhaXJ0aW1lX21jc19ncm91cHNbXSA9 IHsKKwlNQ1NfR1JPVVAoMSwgMCwgQldfMjApLAorCU1DU19HUk9VUCgyLCAwLCBCV18yMCksCisJ TUNTX0dST1VQKDMsIDAsIEJXXzIwKSwKKwlNQ1NfR1JPVVAoNCwgMCwgQldfMjApLAorCisJTUNT X0dST1VQKDEsIDEsIEJXXzIwKSwKKwlNQ1NfR1JPVVAoMiwgMSwgQldfMjApLAorCU1DU19HUk9V UCgzLCAxLCBCV18yMCksCisJTUNTX0dST1VQKDQsIDEsIEJXXzIwKSwKKworCU1DU19HUk9VUCgx LCAwLCBCV180MCksCisJTUNTX0dST1VQKDIsIDAsIEJXXzQwKSwKKwlNQ1NfR1JPVVAoMywgMCwg QldfNDApLAorCU1DU19HUk9VUCg0LCAwLCBCV180MCksCisKKwlNQ1NfR1JPVVAoMSwgMSwgQldf NDApLAorCU1DU19HUk9VUCgyLCAxLCBCV180MCksCisJTUNTX0dST1VQKDMsIDEsIEJXXzQwKSwK KwlNQ1NfR1JPVVAoNCwgMSwgQldfNDApLAorCisJVkhUX0dST1VQKDEsIDAsIEJXXzIwKSwKKwlW SFRfR1JPVVAoMiwgMCwgQldfMjApLAorCVZIVF9HUk9VUCgzLCAwLCBCV18yMCksCisJVkhUX0dS T1VQKDQsIDAsIEJXXzIwKSwKKworCVZIVF9HUk9VUCgxLCAxLCBCV18yMCksCisJVkhUX0dST1VQ KDIsIDEsIEJXXzIwKSwKKwlWSFRfR1JPVVAoMywgMSwgQldfMjApLAorCVZIVF9HUk9VUCg0LCAx LCBCV18yMCksCisKKwlWSFRfR1JPVVAoMSwgMCwgQldfNDApLAorCVZIVF9HUk9VUCgyLCAwLCBC V180MCksCisJVkhUX0dST1VQKDMsIDAsIEJXXzQwKSwKKwlWSFRfR1JPVVAoNCwgMCwgQldfNDAp LAorCisJVkhUX0dST1VQKDEsIDEsIEJXXzQwKSwKKwlWSFRfR1JPVVAoMiwgMSwgQldfNDApLAor CVZIVF9HUk9VUCgzLCAxLCBCV180MCksCisJVkhUX0dST1VQKDQsIDEsIEJXXzQwKSwKKworCVZI VF9HUk9VUCgxLCAwLCBCV184MCksCisJVkhUX0dST1VQKDIsIDAsIEJXXzgwKSwKKwlWSFRfR1JP VVAoMywgMCwgQldfODApLAorCVZIVF9HUk9VUCg0LCAwLCBCV184MCksCisKKwlWSFRfR1JPVVAo MSwgMSwgQldfODApLAorCVZIVF9HUk9VUCgyLCAxLCBCV184MCksCisJVkhUX0dST1VQKDMsIDEs IEJXXzgwKSwKKwlWSFRfR1JPVVAoNCwgMSwgQldfODApLAorfTsKKworc3RhdGljIHUzMgoraWVl ZTgwMjExX2NhbGNfbGVnYWN5X3JhdGVfZHVyYXRpb24oY29uc3Qgc3RydWN0IGllZWU4MDIxMV9y YXRlICpyYXRlLAorCQkJCSAgICBib29sIHNob3J0X3ByZSwgYm9vbCBjY2ssCisJCQkJICAgIGlu dCBsZW4pCit7CisJdTMyIGR1cmF0aW9uOworCisJaWYgKGNjaykgeworCQlkdXJhdGlvbiA9IDE0 NCArIDQ4OyAvKiBwcmVhbWJsZSArIFBMQ1AgKi8KKwkJaWYgKHNob3J0X3ByZSkKKwkJCWR1cmF0 aW9uID4+PSAxOworCisJCWR1cmF0aW9uICs9IDEwOyAvKiBTSUZTICovCisJfSBlbHNlIHsKKwkJ ZHVyYXRpb24gPSAyMCArIDE2OyAvKiBwcmVtYWJsZSArIFNJRlMgKi8KKwl9CisKKwlsZW4gPDw9 IDM7CisJZHVyYXRpb24gKz0gKGxlbiAqIDEwKSAvIHJhdGUtPmJpdHJhdGU7CisKKwlyZXR1cm4g ZHVyYXRpb247Cit9CisKK3UzMiBpZWVlODAyMTFfY2FsY19yeF9haXJ0aW1lKHN0cnVjdCBpZWVl ODAyMTFfaHcgKmh3LAorCQkJICAgICAgc3RydWN0IGllZWU4MDIxMV9yeF9zdGF0dXMgKnN0YXR1 cywKKwkJCSAgICAgIGludCBsZW4pCit7CisJc3RydWN0IGllZWU4MDIxMV9zdXBwb3J0ZWRfYmFu ZCAqc2JhbmQ7CisJY29uc3Qgc3RydWN0IGllZWU4MDIxMV9yYXRlICpyYXRlOworCWJvb2wgc2dp ID0gc3RhdHVzLT5lbmNfZmxhZ3MgJiBSWF9FTkNfRkxBR19TSE9SVF9HSTsKKwlib29sIHNwID0g c3RhdHVzLT5lbmNfZmxhZ3MgJiBSWF9FTkNfRkxBR19TSE9SVFBSRTsKKwlpbnQgYncsIHN0cmVh bXM7CisJdTMyIGR1cmF0aW9uOworCWludCBncm91cCwgaWR4OworCWJvb2wgY2NrOworCisJc3dp dGNoIChzdGF0dXMtPmJ3KSB7CisJY2FzZSBSQVRFX0lORk9fQldfMjA6CisJCWJ3ID0gQldfMjA7 CisJCWJyZWFrOworCWNhc2UgUkFURV9JTkZPX0JXXzQwOgorCQlidyA9IEJXXzQwOworCQlicmVh azsKKwljYXNlIFJBVEVfSU5GT19CV184MDoKKwkJYncgPSBCV184MDsKKwkJYnJlYWs7CisJZGVm YXVsdDoKKwkJV0FSTl9PTl9PTkNFKDEpOworCQlyZXR1cm4gMDsKKwl9CisKKwlzd2l0Y2ggKHN0 YXR1cy0+ZW5jb2RpbmcpIHsKKwljYXNlIFJYX0VOQ19MRUdBQ1k6CisJCWlmIChXQVJOX09OX09O Q0Uoc3RhdHVzLT5iYW5kID4gTkw4MDIxMV9CQU5EXzVHSFopKQorCQkJcmV0dXJuIDA7CisKKwkJ c2JhbmQgPSBody0+d2lwaHktPmJhbmRzW3N0YXR1cy0+YmFuZF07CisJCWlmICghc2JhbmQgfHwg c3RhdHVzLT5yYXRlX2lkeCA+IHNiYW5kLT5uX2JpdHJhdGVzKQorCQkJcmV0dXJuIDA7CisKKwkJ cmF0ZSA9ICZzYmFuZC0+Yml0cmF0ZXNbc3RhdHVzLT5yYXRlX2lkeF07CisJCWNjayA9IChzdGF0 dXMtPnJhdGVfaWR4IDwgQ0NLX05VTV9SQVRFUyk7CisKKwkJcmV0dXJuIGllZWU4MDIxMV9jYWxj X2xlZ2FjeV9yYXRlX2R1cmF0aW9uKHJhdGUsIHNwLCBjY2ssIGxlbik7CisKKwljYXNlIFJYX0VO Q19WSFQ6CisJCXN0cmVhbXMgPSBzdGF0dXMtPm5zczsKKwkJaWR4ID0gc3RhdHVzLT5yYXRlX2lk eDsKKwkJZ3JvdXAgPSBWSFRfR1JPVVBfSURYKHN0cmVhbXMsIHNnaSwgYncpOworCQlicmVhazsK KwljYXNlIFJYX0VOQ19IVDoKKwkJc3RyZWFtcyA9ICgoc3RhdHVzLT5yYXRlX2lkeCA+PiAzKSAm IDMpICsgMTsKKwkJaWR4ID0gc3RhdHVzLT5yYXRlX2lkeCAmIDc7CisJCWdyb3VwID0gSFRfR1JP VVBfSURYKHN0cmVhbXMsIHNnaSwgYncpOworCQlicmVhazsKKwlkZWZhdWx0OgorCQlXQVJOX09O X09OQ0UoMSk7CisJCXJldHVybiAwOworCX0KKworCWlmIChXQVJOX09OX09OQ0Uoc3RyZWFtcyA+ IDQpKQorCQlyZXR1cm4gMDsKKworCWR1cmF0aW9uID0gYWlydGltZV9tY3NfZ3JvdXBzW2dyb3Vw XS5kdXJhdGlvbltpZHhdOworCWR1cmF0aW9uIDw8PSBhaXJ0aW1lX21jc19ncm91cHNbZ3JvdXBd LnNoaWZ0OworCWR1cmF0aW9uICo9IGxlbjsKKwlkdXJhdGlvbiAvPSBBVkdfUEtUX1NJWkU7CisJ ZHVyYXRpb24gLz0gMTAyNDsKKworCWR1cmF0aW9uICs9IDM2ICsgKHN0cmVhbXMgPDwgMik7CisK KwlyZXR1cm4gZHVyYXRpb247Cit9CisKK3UzMiBpZWVlODAyMTFfY2FsY190eF9haXJ0aW1lX3Jh dGUoc3RydWN0IGllZWU4MDIxMV9odyAqaHcsCisJCQkJICAgc3RydWN0IGllZWU4MDIxMV90eF9y YXRlICpyYXRlLAorCQkJCSAgIHU4IGJhbmQsIGludCBsZW4pCit7CisJc3RydWN0IGllZWU4MDIx MV9yeF9zdGF0dXMgc3RhdCA9IHsKKwkJLmJhbmQgPSBiYW5kLAorCX07CisKKwlpZiAocmF0ZS0+ aWR4IDwgMCB8fCAhcmF0ZS0+Y291bnQpCisJCXJldHVybiAwOworCisJaWYgKHJhdGUtPmZsYWdz ICYgSUVFRTgwMjExX1RYX1JDXzgwX01IWl9XSURUSCkKKwkJc3RhdC5idyA9IFJBVEVfSU5GT19C V184MDsKKwllbHNlIGlmIChyYXRlLT5mbGFncyAmIElFRUU4MDIxMV9UWF9SQ180MF9NSFpfV0lE VEgpCisJCXN0YXQuYncgPSBSQVRFX0lORk9fQldfNDA7CisJZWxzZQorCQlzdGF0LmJ3ID0gUkFU RV9JTkZPX0JXXzIwOworCisJc3RhdC5lbmNfZmxhZ3MgPSAwOworCWlmIChyYXRlLT5mbGFncyAm IElFRUU4MDIxMV9UWF9SQ19VU0VfU0hPUlRfUFJFQU1CTEUpCisJCXN0YXQuZW5jX2ZsYWdzIHw9 IFJYX0VOQ19GTEFHX1NIT1JUUFJFOworCWlmIChyYXRlLT5mbGFncyAmIElFRUU4MDIxMV9UWF9S Q19TSE9SVF9HSSkKKwkJc3RhdC5lbmNfZmxhZ3MgfD0gUlhfRU5DX0ZMQUdfU0hPUlRfR0k7CisK KwlzdGF0LnJhdGVfaWR4ID0gcmF0ZS0+aWR4OworCWlmIChyYXRlLT5mbGFncyAmIElFRUU4MDIx MV9UWF9SQ19WSFRfTUNTKSB7CisJCXN0YXQuZW5jb2RpbmcgPSBSWF9FTkNfVkhUOworCQlzdGF0 LnJhdGVfaWR4ID0gaWVlZTgwMjExX3JhdGVfZ2V0X3ZodF9tY3MocmF0ZSk7CisJCXN0YXQubnNz ID0gaWVlZTgwMjExX3JhdGVfZ2V0X3ZodF9uc3MocmF0ZSk7CisJfSBlbHNlIGlmIChyYXRlLT5m bGFncyAmIElFRUU4MDIxMV9UWF9SQ19NQ1MpIHsKKwkJc3RhdC5lbmNvZGluZyA9IFJYX0VOQ19I VDsKKwl9IGVsc2UgeworCQlzdGF0LmVuY29kaW5nID0gUlhfRU5DX0xFR0FDWTsKKwl9CisKKwly ZXR1cm4gaWVlZTgwMjExX2NhbGNfcnhfYWlydGltZShodywgJnN0YXQsIGxlbik7Cit9CisKK3Uz MiBpZWVlODAyMTFfY2FsY190eF9haXJ0aW1lKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LAorCQkJ ICAgICAgc3RydWN0IGllZWU4MDIxMV90eF9pbmZvICppbmZvLAorCQkJICAgICAgaW50IGxlbikK K3sKKwl1MzIgZHVyYXRpb24gPSAwOworCWludCBpOworCisJZm9yIChpID0gMDsgaSA8IEFSUkFZ X1NJWkUoaW5mby0+c3RhdHVzLnJhdGVzKTsgaSsrKSB7CisJCXN0cnVjdCBpZWVlODAyMTFfdHhf cmF0ZSAqcmF0ZSA9ICZpbmZvLT5zdGF0dXMucmF0ZXNbaV07CisJCXUzMiBjdXJfZHVyYXRpb247 CisKKwkJY3VyX2R1cmF0aW9uID0gaWVlZTgwMjExX2NhbGNfdHhfYWlydGltZV9yYXRlKGh3LCBy YXRlLAorCQkJCQkJCSAgICAgIGluZm8tPmJhbmQsIGxlbik7CisJCWlmICghY3VyX2R1cmF0aW9u KQorCQkJYnJlYWs7CisKKwkJZHVyYXRpb24gKz0gY3VyX2R1cmF0aW9uICogcmF0ZS0+Y291bnQ7 CisJfQorCisJcmV0dXJuIGR1cmF0aW9uOworfQorRVhQT1JUX1NZTUJPTF9HUEwoaWVlZTgwMjEx X2NhbGNfdHhfYWlydGltZSk7CisKKwordTMyIGllZWU4MDIxMV9jYWxjX2V4cGVjdGVkX3R4X2Fp cnRpbWUoc3RydWN0IGllZWU4MDIxMV9odyAqaHcsCisJCQkJICAgICAgIHN0cnVjdCBpZWVlODAy MTFfdmlmICp2aWYsCisJCQkJICAgICAgIHN0cnVjdCBpZWVlODAyMTFfc3RhICpwdWJzdGEsCisJ CQkJICAgICAgIGludCBsZW4pCit7CisJc3RydWN0IGllZWU4MDIxMV9zdXBwb3J0ZWRfYmFuZCAq c2JhbmQ7CisJc3RydWN0IGllZWU4MDIxMV9jaGFuY3R4X2NvbmYgKmNvbmY7CisJc3RydWN0IGll ZWU4MDIxMV9yYXRlICpyYXRlOworCXN0cnVjdCBzdGFfaW5mbyAqc3RhOworCXU4IGJhbmQgPSAw OworCisJbGVuICs9IDM4OyAvKiBFdGhlcm5ldCBoZWFkZXIgbGVuZ3RoICovCisKKwljb25mID0g cmN1X2RlcmVmZXJlbmNlKHZpZi0+Y2hhbmN0eF9jb25mKTsKKwlpZiAoY29uZikKKwkJYmFuZCA9 IGNvbmYtPmRlZi5jaGFuLT5iYW5kOworCisJaWYgKHB1YnN0YSkgeworCQlzdGEgID0gY29udGFp bmVyX29mKHB1YnN0YSwgc3RydWN0IHN0YV9pbmZvLCBzdGEpOworCQlyZXR1cm4gaWVlZTgwMjEx X2NhbGNfdHhfYWlydGltZV9yYXRlKGh3LCAmc3RhLT50eF9zdGF0cy5sYXN0X3JhdGUsCisJCQkJ CQkgICAgICBiYW5kLCBsZW4pOworCX0KKworCWlmICghY29uZikKKwkJcmV0dXJuIDA7CisKKwkv KiBObyBzdGF0aW9uIHRvIGdldCBsYXRlc3QgcmF0ZSBmcm9tLCBzbyBjYWxjdWxhdGUgdGhlCisJ ICogd29yc3QtY2FzZSBkdXJhdGlvbiBmb3IgdGhlIGxvd2VzdCByYXRlLgorCSAqLworCXNiYW5k ID0gaHctPndpcGh5LT5iYW5kc1tiYW5kXTsKKwlyYXRlID0gJnNiYW5kLT5iaXRyYXRlc1swXTsK KworCXJldHVybiBpZWVlODAyMTFfY2FsY19sZWdhY3lfcmF0ZV9kdXJhdGlvbihyYXRlLCBmYWxz ZSwgdHJ1ZSwgbGVuKTsKK30KZGlmZiAtLWdpdCBhL25ldC9tYWM4MDIxMS9pZWVlODAyMTFfaS5o IGIvbmV0L21hYzgwMjExL2llZWU4MDIxMV9pLmgKaW5kZXggMDU0MDZlOWMwNWIzLi4yMjVlYTRl M2NkNzYgMTAwNjQ0Ci0tLSBhL25ldC9tYWM4MDIxMS9pZWVlODAyMTFfaS5oCisrKyBiL25ldC9t YWM4MDIxMS9pZWVlODAyMTFfaS5oCkBAIC0yMjQ5LDYgKzIyNDksMTAgQEAgY29uc3QgY2hhciAq aWVlZTgwMjExX2dldF9yZWFzb25fY29kZV9zdHJpbmcodTE2IHJlYXNvbl9jb2RlKTsKIAogZXh0 ZXJuIGNvbnN0IHN0cnVjdCBldGh0b29sX29wcyBpZWVlODAyMTFfZXRodG9vbF9vcHM7CiAKK3Uz MiBpZWVlODAyMTFfY2FsY19leHBlY3RlZF90eF9haXJ0aW1lKHN0cnVjdCBpZWVlODAyMTFfaHcg Kmh3LAorCQkJCSAgICAgICBzdHJ1Y3QgaWVlZTgwMjExX3ZpZiAqdmlmLAorCQkJCSAgICAgICBz dHJ1Y3QgaWVlZTgwMjExX3N0YSAqcHVic3RhLAorCQkJCSAgICAgICBpbnQgbGVuKTsKICNpZmRl ZiBDT05GSUdfTUFDODAyMTFfTk9JTkxJTkUKICNkZWZpbmUgZGVidWdfbm9pbmxpbmUgbm9pbmxp bmUKICNlbHNlCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X18KYXRoMTBrIG1haWxpbmcgbGlzdAphdGgxMGtAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8v bGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2F0aDEwawo=