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.9 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 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 2BC58ECE596 for ; Tue, 15 Oct 2019 17:19:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E163A20854 for ; Tue, 15 Oct 2019 17:19:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="BkIwUAii" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730906AbfJORTK (ORCPT ); Tue, 15 Oct 2019 13:19:10 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:31569 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730856AbfJORTH (ORCPT ); Tue, 15 Oct 2019 13:19:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571159946; 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=U2B+RQcc+GBcfes1Irvb9PkgSokPNhyOEN8//bJUpHA=; b=BkIwUAiinI5Q3h2oyD9Q17AwtCTyjvM9D7Ub4ES0aZvU+cF91jM7nQZfeEMBZO05My4/DG /CQaa2xsvbQgQOywdNZbLpDqKwIcYPOouDXEpCJ9ujGRhGugv7PnfnAzLPB+h3oWeNXxGo zU+VRJNe/TbCk4kKTo38e9UxGsCiN4o= Received: from mail-lf1-f70.google.com (mail-lf1-f70.google.com [209.85.167.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-193-kQJZ3eIJN6KAzx7f50gXAA-1; Tue, 15 Oct 2019 13:19:03 -0400 Received: by mail-lf1-f70.google.com with SMTP id w22so3927083lfe.2 for ; Tue, 15 Oct 2019 10:19:03 -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=T6qHqaS13xJ+wOnFKPV4Xv6wH5SCpjGm2KAC5stfSZA=; b=bAjiXcEBi8k4+mz0M9+aZbL1pXvHpxqj2wmotw+D1AcUJKRyOC3033tO+L0wMn22Wb FNzTjiZFtwFQNj1DCOajB0t74nqxgLJvbyJNWy1kycUbSLPcnXWICw2SHQRU9mmtJNUi a7iQvg10qd0ImNEBl0LSg+VWYc3rVVp/Vc/dcgIru6hZ/dxfYNFpQNDl1agFzGAXwfFT AU4gqtLx/WfYKdxQ5jjaveu10sd0wfiH5laFW3CNty2sDD860SFiqva8Isg5y+kOmCdN AoubzQBcsDNHtO7IS9Z8wgbiEonknml5J/SyvhqxkcOc/PBoupJ6vWLMpqxPn6JkcU4u 16YQ== X-Gm-Message-State: APjAAAUk8AsxXnut+FCP//xWl0BGIGFnwgtKdjbEXnNbIvwczHRiTeo9 kZ5kUXjAKTlghRBnUBJXWfp81Me/YanUwPQEU6cUfo9aPWfzSRrjqSlebe6XcbIS9SFWJPBg+5J I5lE6aYgXxT6j+qqO6Yq6moedIcw= X-Received: by 2002:a2e:8684:: with SMTP id l4mr22699957lji.53.1571159941988; Tue, 15 Oct 2019 10:19:01 -0700 (PDT) X-Google-Smtp-Source: APXvYqwxh5NICgmbnRnEbvnnS4YCs2kIeYMu3ff45ye0NEfbHFfVfZPldYNfM6grnvEWjoIqn+QSsg== X-Received: by 2002:a2e:8684:: with SMTP id l4mr22699907lji.53.1571159941081; Tue, 15 Oct 2019 10:19:01 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk (borgediget.toke.dk. [85.204.121.218]) by smtp.gmail.com with ESMTPSA id u26sm5233078lfd.19.2019.10.15.10.19.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Oct 2019 10:19:00 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id CBD6A1803A8; Tue, 15 Oct 2019 19:18:59 +0200 (CEST) Subject: [PATCH v2 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: Tue, 15 Oct 2019 19:18:59 +0200 Message-ID: <157115993975.2500430.3838554513349536280.stgit@toke.dk> In-Reply-To: <157115993755.2500430.12214017471129215800.stgit@toke.dk> References: <157115993755.2500430.12214017471129215800.stgit@toke.dk> User-Agent: StGit/0.20 MIME-Version: 1.0 X-MC-Unique: kQJZ3eIJN6KAzx7f50gXAA-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 | 375 ++++++++++++++++++++++++++++++++++++++++= ++++ net/mac80211/ieee80211_i.h | 4=20 4 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 net/mac80211/airtime.c diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 49f8ea0af5f8..7619eb74d612 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -6434,4 +6434,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..7a18d5405756 --- /dev/null +++ b/net/mac80211/airtime.c @@ -0,0 +1,375 @@ +// 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; + +=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-delivery-1.mimecast.com ([207.211.31.120] helo=us-smtp-1.mimecast.com) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTU-0006zR-Oi for ath10k@lists.infradead.org; Tue, 15 Oct 2019 17:19:12 +0000 Received: by mail-lf1-f70.google.com with SMTP id e1so3914670lfb.12 for ; Tue, 15 Oct 2019 10:19:03 -0700 (PDT) Subject: [PATCH v2 2/4] mac80211: Import airtime calculation code from mt76 From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= Date: Tue, 15 Oct 2019 19:18:59 +0200 Message-ID: <157115993975.2500430.3838554513349536280.stgit@toke.dk> In-Reply-To: <157115993755.2500430.12214017471129215800.stgit@toke.dk> References: <157115993755.2500430.12214017471129215800.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 aXJ0aW1lLmMgICAgIHwgIDM3NSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKwogbmV0L21hYzgwMjExL2llZWU4MDIxMV9pLmggfCAgICA0IAogNCBmaWxlcyBjaGFu Z2VkLCAzOTUgaW5zZXJ0aW9ucygrKSwgMSBkZWxldGlvbigtKQogY3JlYXRlIG1vZGUgMTAwNjQ0 IG5ldC9tYWM4MDIxMS9haXJ0aW1lLmMKCmRpZmYgLS1naXQgYS9pbmNsdWRlL25ldC9tYWM4MDIx MS5oIGIvaW5jbHVkZS9uZXQvbWFjODAyMTEuaAppbmRleCA0OWY4ZWEwYWY1ZjguLjc2MTllYjc0 ZDYxMiAxMDA2NDQKLS0tIGEvaW5jbHVkZS9uZXQvbWFjODAyMTEuaAorKysgYi9pbmNsdWRlL25l dC9tYWM4MDIxMS5oCkBAIC02NDM0LDQgKzY0MzQsMTggQEAgdm9pZCBpZWVlODAyMTFfbmFuX2Z1 bmNfbWF0Y2goc3RydWN0IGllZWU4MDIxMV92aWYgKnZpZiwKIAkJCSAgICAgIHN0cnVjdCBjZmc4 MDIxMV9uYW5fbWF0Y2hfcGFyYW1zICptYXRjaCwKIAkJCSAgICAgIGdmcF90IGdmcCk7CiAKKy8q KgorICogaWVlZTgwMjExX2NhbGNfdHhfYWlydGltZSAtIGNhbGN1bGF0ZSBlc3RpbWF0ZWQgdHJh bnNtaXNzaW9uIGFpcnRpbWUuCisgKgorICogVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIHRoZSBl c3RpbWF0ZWQgYWlydGltZSB1c2FnZSBvZiBhIGZyYW1lIGJhc2VkIG9uIHRoZQorICogcmF0ZSBp bmZvcm1hdGlvbiBpbiB0aGUgVFggaW5mbyBzdHJ1Y3QgYW5kIHRoZSBmcmFtZSBsZW5ndGguCisg KgorICogQGh3OiBwb2ludGVyIGFzIG9idGFpbmVkIGZyb20gaWVlZTgwMjExX2FsbG9jX2h3KCkK KyAqIEBpbmZvOiAmc3RydWN0IGllZWU4MDIxMV90eF9pbmZvIG9mIHRoZSBmcmFtZS4KKyAqIEBs ZW46IGZyYW1lIGxlbmd0aCBpbiBieXRlcworICovCit1MzIgaWVlZTgwMjExX2NhbGNfdHhfYWly dGltZShzdHJ1Y3QgaWVlZTgwMjExX2h3ICpodywKKwkJCSAgICAgIHN0cnVjdCBpZWVlODAyMTFf dHhfaW5mbyAqaW5mbywKKwkJCSAgICAgIGludCBsZW4pOworCiAjZW5kaWYgLyogTUFDODAyMTFf SCAqLwpkaWZmIC0tZ2l0IGEvbmV0L21hYzgwMjExL01ha2VmaWxlIGIvbmV0L21hYzgwMjExL01h a2VmaWxlCmluZGV4IDRmMDNlYmU3MzJmYS4uNmNiYjEyODZkNmMwIDEwMDY0NAotLS0gYS9uZXQv bWFjODAyMTEvTWFrZWZpbGUKKysrIGIvbmV0L21hYzgwMjExL01ha2VmaWxlCkBAIC0zMiw3ICsz Miw4IEBAIG1hYzgwMjExLXkgOj0gXAogCWNoYW4ubyBcCiAJdHJhY2UubyBtbG1lLm8gXAogCXRk bHMubyBcCi0Jb2NiLm8KKwlvY2IubyBcCisJYWlydGltZS5vCiAKIG1hYzgwMjExLSQoQ09ORklH X01BQzgwMjExX0xFRFMpICs9IGxlZC5vCiBtYWM4MDIxMS0kKENPTkZJR19NQUM4MDIxMV9ERUJV R0ZTKSArPSBcCmRpZmYgLS1naXQgYS9uZXQvbWFjODAyMTEvYWlydGltZS5jIGIvbmV0L21hYzgw MjExL2FpcnRpbWUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjdh MThkNTQwNTc1NgotLS0gL2Rldi9udWxsCisrKyBiL25ldC9tYWM4MDIxMS9haXJ0aW1lLmMKQEAg LTAsMCArMSwzNzUgQEAKKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBJU0MKKy8qCisgKiBD 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 OworCisJY29uZiA9IHJjdV9kZXJlZmVyZW5jZSh2aWYtPmNoYW5jdHhfY29uZik7CisJaWYgKGNv bmYpCisJCWJhbmQgPSBjb25mLT5kZWYuY2hhbi0+YmFuZDsKKworCWlmIChwdWJzdGEpIHsKKwkJ c3RhICA9IGNvbnRhaW5lcl9vZihwdWJzdGEsIHN0cnVjdCBzdGFfaW5mbywgc3RhKTsKKwkJcmV0 dXJuIGllZWU4MDIxMV9jYWxjX3R4X2FpcnRpbWVfcmF0ZShodywgJnN0YS0+dHhfc3RhdHMubGFz dF9yYXRlLAorCQkJCQkJICAgICAgYmFuZCwgbGVuKTsKKwl9CisKKwlpZiAoIWNvbmYpCisJCXJl dHVybiAwOworCisJLyogTm8gc3RhdGlvbiB0byBnZXQgbGF0ZXN0IHJhdGUgZnJvbSwgc28gY2Fs Y3VsYXRlIHRoZQorCSAqIHdvcnN0LWNhc2UgZHVyYXRpb24gZm9yIHRoZSBsb3dlc3QgcmF0ZS4K KwkgKi8KKwlzYmFuZCA9IGh3LT53aXBoeS0+YmFuZHNbYmFuZF07CisJcmF0ZSA9ICZzYmFuZC0+ Yml0cmF0ZXNbMF07CisKKwlyZXR1cm4gaWVlZTgwMjExX2NhbGNfbGVnYWN5X3JhdGVfZHVyYXRp b24ocmF0ZSwgZmFsc2UsIHRydWUsIGxlbik7Cit9CmRpZmYgLS1naXQgYS9uZXQvbWFjODAyMTEv aWVlZTgwMjExX2kuaCBiL25ldC9tYWM4MDIxMS9pZWVlODAyMTFfaS5oCmluZGV4IDA1NDA2ZTlj MDViMy4uMjI1ZWE0ZTNjZDc2IDEwMDY0NAotLS0gYS9uZXQvbWFjODAyMTEvaWVlZTgwMjExX2ku aAorKysgYi9uZXQvbWFjODAyMTEvaWVlZTgwMjExX2kuaApAQCAtMjI0OSw2ICsyMjQ5LDEwIEBA IGNvbnN0IGNoYXIgKmllZWU4MDIxMV9nZXRfcmVhc29uX2NvZGVfc3RyaW5nKHUxNiByZWFzb25f Y29kZSk7CiAKIGV4dGVybiBjb25zdCBzdHJ1Y3QgZXRodG9vbF9vcHMgaWVlZTgwMjExX2V0aHRv b2xfb3BzOwogCit1MzIgaWVlZTgwMjExX2NhbGNfZXhwZWN0ZWRfdHhfYWlydGltZShzdHJ1Y3Qg aWVlZTgwMjExX2h3ICpodywKKwkJCQkgICAgICAgc3RydWN0IGllZWU4MDIxMV92aWYgKnZpZiwK KwkJCQkgICAgICAgc3RydWN0IGllZWU4MDIxMV9zdGEgKnB1YnN0YSwKKwkJCQkgICAgICAgaW50 IGxlbik7CiAjaWZkZWYgQ09ORklHX01BQzgwMjExX05PSU5MSU5FCiAjZGVmaW5lIGRlYnVnX25v aW5saW5lIG5vaW5saW5lCiAjZWxzZQoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fCmF0aDEwayBtYWlsaW5nIGxpc3QKYXRoMTBrQGxpc3RzLmluZnJhZGVh ZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9hdGgxMGsK