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 9096BC43141 for ; Fri, 15 Nov 2019 13:20:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4E04120740 for ; Fri, 15 Nov 2019 13:20:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="XU/4VJiA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727548AbfKONUt (ORCPT ); Fri, 15 Nov 2019 08:20:49 -0500 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:47757 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727472AbfKONUt (ORCPT ); Fri, 15 Nov 2019 08:20:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573824046; 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=E08Pzr06+O9+PjFVSOA/Z5hlhOsPIVZRicJ2i5dDlII=; b=XU/4VJiAcve56NZ7FlFBT3Fdml/1qwvOquKc+PEQZz2IlTnYzUNNC/r/H4z9nFwPFeHXZ1 Op2jXvmBagTk5nYUO3DGfgTx6zSiRkMl1xisJGIAag86FAGdbXmZXz8qDTDluMXttEi+fW YAU5mJJqkKqrnkETzBxmc9gF0OOm/gs= Received: from mail-lj1-f200.google.com (mail-lj1-f200.google.com [209.85.208.200]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-328-aufQ_1UnOcegLtp3T2ozgQ-1; Fri, 15 Nov 2019 08:20:43 -0500 Received: by mail-lj1-f200.google.com with SMTP id n11so1542816lji.9 for ; Fri, 15 Nov 2019 05:20:43 -0800 (PST) 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=XJQMGi2eL7eeEKDLM4OxagL9zjB02JHuHwD89CEpIyg=; b=T6H4p3aIcU/xiScFX7U7cZDgKBLbURjsxNMoOEHQj7wa8YQ9ElX7V1VsJzFzHcHOjQ A/EJyAgoRAgi8m28ydQ3cGqlyWlj5qHcOTxcVam/ocb1xlfNtWGqGurG/9xT2ROoGCt/ GSiH3v/o7ZxrkK1SNibs9CjGIk9LO+fAjN2aFpQwtYW30AMmUbzDkcEcChsB1KFPss9j NsgHEH8J+oYGa2wq7WeKmPvQRJm8HVE1FuKei+qqi2GIs8cJdlC8lOquqLwiPQt6q8bm cq8KMbVYzKyI65snX/I5OXR09co/fdsJCqx2WFEz/os4Xw8ro/PyScP9wUYjfaByxHNM CJdw== X-Gm-Message-State: APjAAAW3xQt8xga+Nk400IfgCdBxzpDB0vf4MOQVb3xqPSgJnS5cBBHj IA9JjWdOXfPzKpSWA+ALQPiANAcmXTz5xczv39NKnIr+SzITPYN/msMdTc8qbG3HQ4l/4lN3Jmd XL9Kw5HpB7VonvqesaTSoL85y+B0= X-Received: by 2002:ac2:5598:: with SMTP id v24mr11234907lfg.30.1573824041758; Fri, 15 Nov 2019 05:20:41 -0800 (PST) X-Google-Smtp-Source: APXvYqx9ZOhZmHeJdT+ii17d8uiB5r1NUXE+tqvmpcVvYCIMtLlp85FFsArJur/WJqPS+/Ci96kgyQ== X-Received: by 2002:ac2:5598:: with SMTP id v24mr11234862lfg.30.1573824041145; Fri, 15 Nov 2019 05:20:41 -0800 (PST) Received: from alrua-x1.borgediget.toke.dk (borgediget.toke.dk. [85.204.121.218]) by smtp.gmail.com with ESMTPSA id s11sm3862166ljo.42.2019.11.15.05.20.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Nov 2019 05:20:39 -0800 (PST) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 1420A1818C5; Fri, 15 Nov 2019 14:20:39 +0100 (CET) Subject: [PATCH v9 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: Fri, 15 Nov 2019 14:20:39 +0100 Message-ID: <157382403899.580235.13678327417572732513.stgit@toke.dk> In-Reply-To: <157382403672.580235.12525941420808058808.stgit@toke.dk> References: <157382403672.580235.12525941420808058808.stgit@toke.dk> User-Agent: StGit/0.21 MIME-Version: 1.0 X-MC-Unique: aufQ_1UnOcegLtp3T2ozgQ-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. The airtime.c file is copied verbatim from the mt76 driver, and adjusted to be usable in mac80211. This involves: - Switching to mac80211 data structures. - Adding support for 160 MHz channels and HE mode. - Moving the symbol and duration calculations around a bit to avoid rounding with the higher rates and longer symbol times used for HE rates. The per-rate TX rate calculation is also split out to its own function so it can be used directly for the AQL calculations later. Signed-off-by: Toke H=C3=B8iland-J=C3=B8rgensen --- include/net/mac80211.h | 29 ++ net/mac80211/Makefile | 3=20 net/mac80211/airtime.c | 597 ++++++++++++++++++++++++++++++++++++++++= ++++ net/mac80211/ieee80211_i.h | 4=20 4 files changed, 632 insertions(+), 1 deletion(-) create mode 100644 net/mac80211/airtime.c diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c643a19dce96..6fc26a051ba0 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -6424,4 +6424,33 @@ 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_rx_airtime - calculate estimated transmission airtime fo= r RX. + * + * This function calculates the estimated airtime usage of a frame based o= n the + * rate information in the RX status struct and the frame length. + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @status: &struct ieee80211_rx_status containing the transmission rate + * information. + * @len: frame length in bytes + */ +u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw, +=09=09=09 struct ieee80211_rx_status *status, +=09=09=09 int len); + +/** + * ieee80211_calc_tx_airtime - calculate estimated transmission airtime fo= r TX. + * + * 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..0c2a0bb94727 --- /dev/null +++ b/net/mac80211/airtime.c @@ -0,0 +1,597 @@ +// 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 kilo-symbols (symbols * 1024) for a packet with (bps) bits pe= r + * symbol. We use k-symbols to avoid rounding in the _TIME macros below. + */ +#define MCS_N_KSYMS(bps) DIV_ROUND_UP(MCS_NBITS << 10, (bps)) + +/* Transmission time (in 1024 * usec) for a packet containing (ksyms) * 10= 24 + * symbols. + */ +#define MCS_SYMBOL_TIME(sgi, ksyms)=09=09=09=09=09\ +=09(sgi ?=09=09=09=09=09=09=09=09\ +=09 ((ksyms) * 4 * 18) / 20 :=09=09/* 3.6 us per sym */=09\ +=09 ((ksyms) * 4)=09=09=09/* 4.0 us per sym */=09\ +=09) + +/* Transmit duration for the raw data part of an average sized packet */ +#define MCS_DURATION(streams, sgi, bps) \ +=09((u32)MCS_SYMBOL_TIME(sgi, MCS_N_KSYMS((streams) * (bps)))) + +#define MCS_DURATION_S(shift, streams, sgi, bps)=09=09\ +=09((u16)((MCS_DURATION(streams, sgi, bps) >> shift))) + +/* These should match the values in enum nl80211_he_gi */ +#define HE_GI_08 0 +#define HE_GI_16 1 +#define HE_GI_32 2 + +/* Transmission time (1024 usec) for a packet containing (ksyms) * k-symbo= ls */ +#define HE_SYMBOL_TIME(gi, ksyms)=09=09=09=09=09\ +=09(gi =3D=3D HE_GI_08 ?=09=09=09=09=09=09\ +=09 ((ksyms) * 16 * 17) / 20 :=09=09/* 13.6 us per sym */=09\ +=09 (gi =3D=3D HE_GI_16 ?=09=09=09=09=09=09\ +=09 ((ksyms) * 16 * 18) / 20 :=09=09/* 14.4 us per sym */=09\ +=09 ((ksyms) * 16)=09=09=09/* 16.0 us per sym */=09\ +=09 )) + +/* Transmit duration for the raw data part of an average sized packet */ +#define HE_DURATION(streams, gi, bps) \ +=09((u32)HE_SYMBOL_TIME(gi, MCS_N_KSYMS((streams) * (bps)))) + +#define HE_DURATION_S(shift, streams, gi, bps)=09=09\ +=09(HE_DURATION(streams, gi, bps) >> shift) + +#define BW_20=09=09=090 +#define BW_40=09=09=091 +#define BW_80=09=09=092 +#define BW_160=09=09=093 + +/* + * 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=098 /* BW(=3D4) * SGI(=3D2) */ + +#define IEEE80211_HE_MAX_STREAMS=098 +#define IEEE80211_HE_STREAM_GROUPS=0912 /* BW(=3D4) * GI(=3D3) */ + +#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_HE_GROUPS_NB=09(IEEE80211_HE_MAX_STREAMS *=09\ +=09=09=09=09 IEEE80211_HE_STREAM_GROUPS) +#define IEEE80211_GROUPS_NB=09(IEEE80211_HT_GROUPS_NB +=09\ +=09=09=09=09 IEEE80211_VHT_GROUPS_NB +=09\ +=09=09=09=09 IEEE80211_HE_GROUPS_NB) + +#define IEEE80211_HT_GROUP_0=090 +#define IEEE80211_VHT_GROUP_0=09(IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUP= S_NB) +#define IEEE80211_HE_GROUP_0=09(IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROU= PS_NB) + +#define MCS_GROUP_RATES=09=0912 + +#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_S(_s, _streams, _sgi, _ht40 ? 54 : 26),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 108 : 52),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 162 : 78),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 216 : 104),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 324 : 156),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 432 : 208),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 486 : 234),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 540 : 260)=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 IEEE80211_MAX_STREAMS * 2 * (_bw) +=09=09=09=09\ +=09 IEEE80211_MAX_STREAMS * (_sgi) +=09=09=09=09\ +=09 (_streams) - 1) + +#define BW2VBPS(_bw, r4, r3, r2, r1)=09=09=09=09=09\ +=09(_bw =3D=3D BW_160 ? r4 : _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_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 234, 117, 54, 26)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 468, 234, 108, 52)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 702, 351, 162, 78)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 936, 468, 216, 104)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 1404, 702, 324, 156)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 1872, 936, 432, 208)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 2106, 1053, 486, 234)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 2340, 1170, 540, 260)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 2808, 1404, 648, 312)),=09\ +=09=09MCS_DURATION_S(_s, _streams, _sgi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 3120, 1560, 720, 346))=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, 243, 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)) + + +#define HE_GROUP_IDX(_streams, _gi, _bw)=09=09=09=09\ +=09(IEEE80211_HE_GROUP_0 +=09=09=09=09=09\ +=09 IEEE80211_HE_MAX_STREAMS * 2 * (_bw) +=09=09=09\ +=09 IEEE80211_HE_MAX_STREAMS * (_gi) +=09=09=09=09\ +=09 (_streams) - 1) + +#define __HE_GROUP(_streams, _gi, _bw, _s)=09=09=09=09\ +=09[HE_GROUP_IDX(_streams, _gi, _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=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 979, 489, 230, 115)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 1958, 979, 475, 230)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 2937, 1468, 705, 345)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 3916, 1958, 936, 475)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 5875, 2937, 1411, 705)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 7833, 3916, 1872, 936)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 8827, 4406, 2102, 1051)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 9806, 4896, 2347, 1166)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 11764, 5875, 2808, 1411)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 13060, 6523, 3124, 1555)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 14702, 7344, 3513, 1756)),=09\ +=09=09HE_DURATION_S(_s, _streams, _gi,=09=09=09\ +=09=09=09 BW2VBPS(_bw, 16329, 8164, 3902, 1944))=09\ + }=09=09=09=09=09=09=09=09\ +} + +#define HE_GROUP_SHIFT(_streams, _gi, _bw)=09=09=09=09\ +=09GROUP_SHIFT(HE_DURATION(_streams, _gi,=09=09=09\ +=09=09=09=09BW2VBPS(_bw, 979, 489, 230, 115))) + +#define HE_GROUP(_streams, _gi, _bw)=09=09=09=09=09\ +=09__HE_GROUP(_streams, _gi, _bw,=09=09=09=09\ +=09=09 HE_GROUP_SHIFT(_streams, _gi, _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), + +=09VHT_GROUP(1, 0, BW_160), +=09VHT_GROUP(2, 0, BW_160), +=09VHT_GROUP(3, 0, BW_160), +=09VHT_GROUP(4, 0, BW_160), + +=09VHT_GROUP(1, 1, BW_160), +=09VHT_GROUP(2, 1, BW_160), +=09VHT_GROUP(3, 1, BW_160), +=09VHT_GROUP(4, 1, BW_160), + +=09HE_GROUP(1, HE_GI_08, BW_20), +=09HE_GROUP(2, HE_GI_08, BW_20), +=09HE_GROUP(3, HE_GI_08, BW_20), +=09HE_GROUP(4, HE_GI_08, BW_20), +=09HE_GROUP(5, HE_GI_08, BW_20), +=09HE_GROUP(6, HE_GI_08, BW_20), +=09HE_GROUP(7, HE_GI_08, BW_20), +=09HE_GROUP(8, HE_GI_08, BW_20), + +=09HE_GROUP(1, HE_GI_16, BW_20), +=09HE_GROUP(2, HE_GI_16, BW_20), +=09HE_GROUP(3, HE_GI_16, BW_20), +=09HE_GROUP(4, HE_GI_16, BW_20), +=09HE_GROUP(5, HE_GI_16, BW_20), +=09HE_GROUP(6, HE_GI_16, BW_20), +=09HE_GROUP(7, HE_GI_16, BW_20), +=09HE_GROUP(8, HE_GI_16, BW_20), + +=09HE_GROUP(1, HE_GI_32, BW_20), +=09HE_GROUP(2, HE_GI_32, BW_20), +=09HE_GROUP(3, HE_GI_32, BW_20), +=09HE_GROUP(4, HE_GI_32, BW_20), +=09HE_GROUP(5, HE_GI_32, BW_20), +=09HE_GROUP(6, HE_GI_32, BW_20), +=09HE_GROUP(7, HE_GI_32, BW_20), +=09HE_GROUP(8, HE_GI_32, BW_20), + +=09HE_GROUP(1, HE_GI_08, BW_40), +=09HE_GROUP(2, HE_GI_08, BW_40), +=09HE_GROUP(3, HE_GI_08, BW_40), +=09HE_GROUP(4, HE_GI_08, BW_40), +=09HE_GROUP(5, HE_GI_08, BW_40), +=09HE_GROUP(6, HE_GI_08, BW_40), +=09HE_GROUP(7, HE_GI_08, BW_40), +=09HE_GROUP(8, HE_GI_08, BW_40), + +=09HE_GROUP(1, HE_GI_16, BW_40), +=09HE_GROUP(2, HE_GI_16, BW_40), +=09HE_GROUP(3, HE_GI_16, BW_40), +=09HE_GROUP(4, HE_GI_16, BW_40), +=09HE_GROUP(5, HE_GI_16, BW_40), +=09HE_GROUP(6, HE_GI_16, BW_40), +=09HE_GROUP(7, HE_GI_16, BW_40), +=09HE_GROUP(8, HE_GI_16, BW_40), + +=09HE_GROUP(1, HE_GI_32, BW_40), +=09HE_GROUP(2, HE_GI_32, BW_40), +=09HE_GROUP(3, HE_GI_32, BW_40), +=09HE_GROUP(4, HE_GI_32, BW_40), +=09HE_GROUP(5, HE_GI_32, BW_40), +=09HE_GROUP(6, HE_GI_32, BW_40), +=09HE_GROUP(7, HE_GI_32, BW_40), +=09HE_GROUP(8, HE_GI_32, BW_40), + +=09HE_GROUP(1, HE_GI_08, BW_80), +=09HE_GROUP(2, HE_GI_08, BW_80), +=09HE_GROUP(3, HE_GI_08, BW_80), +=09HE_GROUP(4, HE_GI_08, BW_80), +=09HE_GROUP(5, HE_GI_08, BW_80), +=09HE_GROUP(6, HE_GI_08, BW_80), +=09HE_GROUP(7, HE_GI_08, BW_80), +=09HE_GROUP(8, HE_GI_08, BW_80), + +=09HE_GROUP(1, HE_GI_16, BW_80), +=09HE_GROUP(2, HE_GI_16, BW_80), +=09HE_GROUP(3, HE_GI_16, BW_80), +=09HE_GROUP(4, HE_GI_16, BW_80), +=09HE_GROUP(5, HE_GI_16, BW_80), +=09HE_GROUP(6, HE_GI_16, BW_80), +=09HE_GROUP(7, HE_GI_16, BW_80), +=09HE_GROUP(8, HE_GI_16, BW_80), + +=09HE_GROUP(1, HE_GI_32, BW_80), +=09HE_GROUP(2, HE_GI_32, BW_80), +=09HE_GROUP(3, HE_GI_32, BW_80), +=09HE_GROUP(4, HE_GI_32, BW_80), +=09HE_GROUP(5, HE_GI_32, BW_80), +=09HE_GROUP(6, HE_GI_32, BW_80), +=09HE_GROUP(7, HE_GI_32, BW_80), +=09HE_GROUP(8, HE_GI_32, BW_80), + +=09HE_GROUP(1, HE_GI_08, BW_160), +=09HE_GROUP(2, HE_GI_08, BW_160), +=09HE_GROUP(3, HE_GI_08, BW_160), +=09HE_GROUP(4, HE_GI_08, BW_160), +=09HE_GROUP(5, HE_GI_08, BW_160), +=09HE_GROUP(6, HE_GI_08, BW_160), +=09HE_GROUP(7, HE_GI_08, BW_160), +=09HE_GROUP(8, HE_GI_08, BW_160), + +=09HE_GROUP(1, HE_GI_16, BW_160), +=09HE_GROUP(2, HE_GI_16, BW_160), +=09HE_GROUP(3, HE_GI_16, BW_160), +=09HE_GROUP(4, HE_GI_16, BW_160), +=09HE_GROUP(5, HE_GI_16, BW_160), +=09HE_GROUP(6, HE_GI_16, BW_160), +=09HE_GROUP(7, HE_GI_16, BW_160), +=09HE_GROUP(8, HE_GI_16, BW_160), + +=09HE_GROUP(1, HE_GI_32, BW_160), +=09HE_GROUP(2, HE_GI_32, BW_160), +=09HE_GROUP(3, HE_GI_32, BW_160), +=09HE_GROUP(4, HE_GI_32, BW_160), +=09HE_GROUP(5, HE_GI_32, BW_160), +=09HE_GROUP(6, HE_GI_32, BW_160), +=09HE_GROUP(7, HE_GI_32, BW_160), +=09HE_GROUP(8, HE_GI_32, BW_160), +}; + +static u32 +ieee80211_calc_legacy_rate_duration(u16 bitrate, bool short_pre, +=09=09=09=09 bool cck, 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) / 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; +=09int group, idx; +=09u32 duration; +=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; +=09case RATE_INFO_BW_160: +=09=09bw =3D BW_160; +=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 rate->flags & IEEE80211_RATE_MANDATORY_B; + +=09=09return ieee80211_calc_legacy_rate_duration(rate->bitrate, sp, +=09=09=09=09=09=09=09 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; +=09case RX_ENC_HE: +=09=09streams =3D status->nss; +=09=09idx =3D status->rate_idx; +=09=09group =3D HE_GROUP_IDX(streams, status->he_gi, bw); +=09=09break; +=09default: +=09=09WARN_ON_ONCE(1); +=09=09return 0; +=09} + +=09if (WARN_ON_ONCE((status->encoding !=3D RX_ENC_HE && streams > 4) || +=09=09=09 (status->encoding =3D=3D RX_ENC_HE && streams > 8))) +=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; +} +EXPORT_SYMBOL_GPL(ieee80211_calc_rx_airtime); + +static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw, +=09=09=09=09=09 struct ieee80211_tx_rate *rate, +=09=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; +=09int rateidx, shift =3D 0; +=09bool cck, short_pream; +=09u32 basic_rates; +=09u8 band =3D 0; +=09u16 rate; + +=09len +=3D 38; /* Ethernet header length */ + +=09conf =3D rcu_dereference(vif->chanctx_conf); +=09if (conf) { +=09=09band =3D conf->def.chan->band; +=09=09shift =3D ieee80211_chandef_get_shift(&conf->def); +=09} + +=09if (pubsta) { +=09=09struct sta_info *sta =3D container_of(pubsta, struct sta_info, +=09=09=09=09=09=09 sta); + +=09=09return ieee80211_calc_tx_airtime_rate(hw, +=09=09=09=09=09=09 &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 worst-case +=09 * duration using the lowest configured basic rate. +=09 */ +=09sband =3D hw->wiphy->bands[band]; + +=09basic_rates =3D vif->bss_conf.basic_rates; +=09short_pream =3D vif->bss_conf.use_short_preamble; + +=09rateidx =3D basic_rates ? ffs(basic_rates) - 1 : 0; +=09rate =3D sband->bitrates[rateidx].bitrate << shift; +=09cck =3D sband->bitrates[rateidx].flags & IEEE80211_RATE_MANDATORY_B; + +=09return ieee80211_calc_legacy_rate_duration(rate, short_pream, cck, 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 1iVbWp-0000s2-6k for ath10k@lists.infradead.org; Fri, 15 Nov 2019 13:20:50 +0000 Received: by mail-lf1-f70.google.com with SMTP id z128so353357lfa.9 for ; Fri, 15 Nov 2019 05:20:43 -0800 (PST) Subject: [PATCH v9 2/4] mac80211: Import airtime calculation code from mt76 From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= Date: Fri, 15 Nov 2019 14:20:39 +0100 Message-ID: <157382403899.580235.13678327417572732513.stgit@toke.dk> In-Reply-To: <157382403672.580235.12525941420808058808.stgit@toke.dk> References: <157382403672.580235.12525941420808058808.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 Zm9yIGFpcnRpbWUgcXVldWUgbGltaXQKY2FsY3VsYXRpb25zLgoKVGhlIGFpcnRpbWUuYyBmaWxl IGlzIGNvcGllZCB2ZXJiYXRpbSBmcm9tIHRoZSBtdDc2IGRyaXZlciwgYW5kIGFkanVzdGVkIHRv CmJlIHVzYWJsZSBpbiBtYWM4MDIxMS4gVGhpcyBpbnZvbHZlczoKCi0gU3dpdGNoaW5nIHRvIG1h YzgwMjExIGRhdGEgc3RydWN0dXJlcy4KLSBBZGRpbmcgc3VwcG9ydCBmb3IgMTYwIE1IeiBjaGFu bmVscyBhbmQgSEUgbW9kZS4KLSBNb3ZpbmcgdGhlIHN5bWJvbCBhbmQgZHVyYXRpb24gY2FsY3Vs YXRpb25zIGFyb3VuZCBhIGJpdCB0byBhdm9pZAogIHJvdW5kaW5nIHdpdGggdGhlIGhpZ2hlciBy YXRlcyBhbmQgbG9uZ2VyIHN5bWJvbCB0aW1lcyB1c2VkIGZvciBIRSByYXRlcy4KClRoZSBwZXIt cmF0ZSBUWCByYXRlIGNhbGN1bGF0aW9uIGlzIGFsc28gc3BsaXQgb3V0IHRvIGl0cyBvd24gZnVu Y3Rpb24gc28KaXQgY2FuIGJlIHVzZWQgZGlyZWN0bHkgZm9yIHRoZSBBUUwgY2FsY3VsYXRpb25z IGxhdGVyLgoKU2lnbmVkLW9mZi1ieTogVG9rZSBIw7hpbGFuZC1Kw7hyZ2Vuc2VuIDx0b2tlQHJl ZGhhdC5jb20+Ci0tLQogaW5jbHVkZS9uZXQvbWFjODAyMTEuaCAgICAgfCAgIDI5ICsrCiBuZXQv bWFjODAyMTEvTWFrZWZpbGUgICAgICB8ICAgIDMgCiBuZXQvbWFjODAyMTEvYWlydGltZS5jICAg ICB8ICA1OTcgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKIG5l dC9tYWM4MDIxMS9pZWVlODAyMTFfaS5oIHwgICAgNCAKIDQgZmlsZXMgY2hhbmdlZCwgNjMyIGlu c2VydGlvbnMoKyksIDEgZGVsZXRpb24oLSkKIGNyZWF0ZSBtb2RlIDEwMDY0NCBuZXQvbWFjODAy MTEvYWlydGltZS5jCgpkaWZmIC0tZ2l0IGEvaW5jbHVkZS9uZXQvbWFjODAyMTEuaCBiL2luY2x1 ZGUvbmV0L21hYzgwMjExLmgKaW5kZXggYzY0M2ExOWRjZTk2Li42ZmMyNmEwNTFiYTAgMTAwNjQ0 Ci0tLSBhL2luY2x1ZGUvbmV0L21hYzgwMjExLmgKKysrIGIvaW5jbHVkZS9uZXQvbWFjODAyMTEu aApAQCAtNjQyNCw0ICs2NDI0LDMzIEBAIHZvaWQgaWVlZTgwMjExX25hbl9mdW5jX21hdGNoKHN0 cnVjdCBpZWVlODAyMTFfdmlmICp2aWYsCiAJCQkgICAgICBzdHJ1Y3QgY2ZnODAyMTFfbmFuX21h dGNoX3BhcmFtcyAqbWF0Y2gsCiAJCQkgICAgICBnZnBfdCBnZnApOwogCisvKioKKyAqIGllZWU4 MDIxMV9jYWxjX3J4X2FpcnRpbWUgLSBjYWxjdWxhdGUgZXN0aW1hdGVkIHRyYW5zbWlzc2lvbiBh aXJ0aW1lIGZvciBSWC4KKyAqCisgKiBUaGlzIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgdGhlIGVzdGlt YXRlZCBhaXJ0aW1lIHVzYWdlIG9mIGEgZnJhbWUgYmFzZWQgb24gdGhlCisgKiByYXRlIGluZm9y bWF0aW9uIGluIHRoZSBSWCBzdGF0dXMgc3RydWN0IGFuZCB0aGUgZnJhbWUgbGVuZ3RoLgorICoK KyAqIEBodzogcG9pbnRlciBhcyBvYnRhaW5lZCBmcm9tIGllZWU4MDIxMV9hbGxvY19odygpCisg KiBAc3RhdHVzOiAmc3RydWN0IGllZWU4MDIxMV9yeF9zdGF0dXMgY29udGFpbmluZyB0aGUgdHJh bnNtaXNzaW9uIHJhdGUKKyAqICAgICAgICAgIGluZm9ybWF0aW9uLgorICogQGxlbjogZnJhbWUg bGVuZ3RoIGluIGJ5dGVzCisgKi8KK3UzMiBpZWVlODAyMTFfY2FsY19yeF9haXJ0aW1lKHN0cnVj dCBpZWVlODAyMTFfaHcgKmh3LAorCQkJICAgICAgc3RydWN0IGllZWU4MDIxMV9yeF9zdGF0dXMg KnN0YXR1cywKKwkJCSAgICAgIGludCBsZW4pOworCisvKioKKyAqIGllZWU4MDIxMV9jYWxjX3R4 X2FpcnRpbWUgLSBjYWxjdWxhdGUgZXN0aW1hdGVkIHRyYW5zbWlzc2lvbiBhaXJ0aW1lIGZvciBU WC4KKyAqCisgKiBUaGlzIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgdGhlIGVzdGltYXRlZCBhaXJ0aW1l IHVzYWdlIG9mIGEgZnJhbWUgYmFzZWQgb24gdGhlCisgKiByYXRlIGluZm9ybWF0aW9uIGluIHRo ZSBUWCBpbmZvIHN0cnVjdCBhbmQgdGhlIGZyYW1lIGxlbmd0aC4KKyAqCisgKiBAaHc6IHBvaW50 ZXIgYXMgb2J0YWluZWQgZnJvbSBpZWVlODAyMTFfYWxsb2NfaHcoKQorICogQGluZm86ICZzdHJ1 Y3QgaWVlZTgwMjExX3R4X2luZm8gb2YgdGhlIGZyYW1lLgorICogQGxlbjogZnJhbWUgbGVuZ3Ro IGluIGJ5dGVzCisgKi8KK3UzMiBpZWVlODAyMTFfY2FsY190eF9haXJ0aW1lKHN0cnVjdCBpZWVl ODAyMTFfaHcgKmh3LAorCQkJICAgICAgc3RydWN0IGllZWU4MDIxMV90eF9pbmZvICppbmZvLAor CQkJICAgICAgaW50IGxlbik7CisKICNlbmRpZiAvKiBNQUM4MDIxMV9IICovCmRpZmYgLS1naXQg YS9uZXQvbWFjODAyMTEvTWFrZWZpbGUgYi9uZXQvbWFjODAyMTEvTWFrZWZpbGUKaW5kZXggNGYw M2ViZTczMmZhLi42Y2JiMTI4NmQ2YzAgMTAwNjQ0Ci0tLSBhL25ldC9tYWM4MDIxMS9NYWtlZmls ZQorKysgYi9uZXQvbWFjODAyMTEvTWFrZWZpbGUKQEAgLTMyLDcgKzMyLDggQEAgbWFjODAyMTEt eSA6PSBcCiAJY2hhbi5vIFwKIAl0cmFjZS5vIG1sbWUubyBcCiAJdGRscy5vIFwKLQlvY2Iubwor CW9jYi5vIFwKKwlhaXJ0aW1lLm8KIAogbWFjODAyMTEtJChDT05GSUdfTUFDODAyMTFfTEVEUykg Kz0gbGVkLm8KIG1hYzgwMjExLSQoQ09ORklHX01BQzgwMjExX0RFQlVHRlMpICs9IFwKZGlmZiAt LWdpdCBhL25ldC9tYWM4MDIxMS9haXJ0aW1lLmMgYi9uZXQvbWFjODAyMTEvYWlydGltZS5jCm5l dyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uMGMyYTBiYjk0NzI3Ci0tLSAv ZGV2L251bGwKKysrIGIvbmV0L21hYzgwMjExL2FpcnRpbWUuYwpAQCAtMCwwICsxLDU5NyBAQAor Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IElTQworLyoKKyAqIENvcHlyaWdodCAoQykgMjAx OSBGZWxpeCBGaWV0a2F1IDxuYmRAbmJkLm5hbWU+CisgKi8KKworI2luY2x1ZGUgPG5ldC9tYWM4 MDIxMS5oPgorI2luY2x1ZGUgImllZWU4MDIxMV9pLmgiCisjaW5jbHVkZSAic3RhX2luZm8uaCIK KworI2RlZmluZSBBVkdfUEtUX1NJWkUJMTAyNAorCisvKiBOdW1iZXIgb2YgYml0cyBmb3IgYW4g YXZlcmFnZSBzaXplZCBwYWNrZXQgKi8KKyNkZWZpbmUgTUNTX05CSVRTIChBVkdfUEtUX1NJWkUg PDwgMykKKworLyogTnVtYmVyIG9mIGtpbG8tc3ltYm9scyAoc3ltYm9scyAqIDEwMjQpIGZvciBh IHBhY2tldCB3aXRoIChicHMpIGJpdHMgcGVyCisgKiBzeW1ib2wuIFdlIHVzZSBrLXN5bWJvbHMg dG8gYXZvaWQgcm91bmRpbmcgaW4gdGhlIF9USU1FIG1hY3JvcyBiZWxvdy4KKyAqLworI2RlZmlu ZSBNQ1NfTl9LU1lNUyhicHMpIERJVl9ST1VORF9VUChNQ1NfTkJJVFMgPDwgMTAsIChicHMpKQor CisvKiBUcmFuc21pc3Npb24gdGltZSAoaW4gMTAyNCAqIHVzZWMpIGZvciBhIHBhY2tldCBjb250 YWluaW5nIChrc3ltcykgKiAxMDI0CisgKiBzeW1ib2xzLgorICovCisjZGVmaW5lIE1DU19TWU1C T0xfVElNRShzZ2ksIGtzeW1zKQkJCQkJXAorCShzZ2kgPwkJCQkJCQkJXAorCSAgKChrc3ltcykg KiA0ICogMTgpIC8gMjAgOgkJLyogMy42IHVzIHBlciBzeW0gKi8JXAorCSAgKChrc3ltcykgKiA0 KQkJCS8qIDQuMCB1cyBwZXIgc3ltICovCVwKKwkpCisKKy8qIFRyYW5zbWl0IGR1cmF0aW9uIGZv ciB0aGUgcmF3IGRhdGEgcGFydCBvZiBhbiBhdmVyYWdlIHNpemVkIHBhY2tldCAqLworI2RlZmlu ZSBNQ1NfRFVSQVRJT04oc3RyZWFtcywgc2dpLCBicHMpIFwKKwkoKHUzMilNQ1NfU1lNQk9MX1RJ TUUoc2dpLCBNQ1NfTl9LU1lNUygoc3RyZWFtcykgKiAoYnBzKSkpKQorCisjZGVmaW5lIE1DU19E VVJBVElPTl9TKHNoaWZ0LCBzdHJlYW1zLCBzZ2ksIGJwcykJCVwKKwkoKHUxNikoKE1DU19EVVJB VElPTihzdHJlYW1zLCBzZ2ksIGJwcykgPj4gc2hpZnQpKSkKKworLyogVGhlc2Ugc2hvdWxkIG1h dGNoIHRoZSB2YWx1ZXMgaW4gZW51bSBubDgwMjExX2hlX2dpICovCisjZGVmaW5lIEhFX0dJXzA4 IDAKKyNkZWZpbmUgSEVfR0lfMTYgMQorI2RlZmluZSBIRV9HSV8zMiAyCisKKy8qIFRyYW5zbWlz c2lvbiB0aW1lICgxMDI0IHVzZWMpIGZvciBhIHBhY2tldCBjb250YWluaW5nIChrc3ltcykgKiBr LXN5bWJvbHMgKi8KKyNkZWZpbmUgSEVfU1lNQk9MX1RJTUUoZ2ksIGtzeW1zKQkJCQkJXAorCShn aSA9PSBIRV9HSV8wOCA/CQkJCQkJXAorCSAoKGtzeW1zKSAqIDE2ICogMTcpIC8gMjAgOgkJLyog MTMuNiB1cyBwZXIgc3ltICovCVwKKwkgKGdpID09IEhFX0dJXzE2ID8JCQkJCQlcCisJICAoKGtz eW1zKSAqIDE2ICogMTgpIC8gMjAgOgkJLyogMTQuNCB1cyBwZXIgc3ltICovCVwKKwkgICgoa3N5 bXMpICogMTYpCQkJLyogMTYuMCB1cyBwZXIgc3ltICovCVwKKwkgKSkKKworLyogVHJhbnNtaXQg ZHVyYXRpb24gZm9yIHRoZSByYXcgZGF0YSBwYXJ0IG9mIGFuIGF2ZXJhZ2Ugc2l6ZWQgcGFja2V0 ICovCisjZGVmaW5lIEhFX0RVUkFUSU9OKHN0cmVhbXMsIGdpLCBicHMpIFwKKwkoKHUzMilIRV9T WU1CT0xfVElNRShnaSwgTUNTX05fS1NZTVMoKHN0cmVhbXMpICogKGJwcykpKSkKKworI2RlZmlu ZSBIRV9EVVJBVElPTl9TKHNoaWZ0LCBzdHJlYW1zLCBnaSwgYnBzKQkJXAorCShIRV9EVVJBVElP TihzdHJlYW1zLCBnaSwgYnBzKSA+PiBzaGlmdCkKKworI2RlZmluZSBCV18yMAkJCTAKKyNkZWZp bmUgQldfNDAJCQkxCisjZGVmaW5lIEJXXzgwCQkJMgorI2RlZmluZSBCV18xNjAJCQkzCisKKy8q CisgKiBEZWZpbmUgZ3JvdXAgc29ydCBvcmRlcjogSFQ0MCAtPiBTR0kgLT4gI3N0cmVhbXMKKyAq LworI2RlZmluZSBJRUVFODAyMTFfTUFYX1NUUkVBTVMJCTQKKyNkZWZpbmUgSUVFRTgwMjExX0hU X1NUUkVBTV9HUk9VUFMJNCAvKiBCVyg9MikgKiBTR0koPTIpICovCisjZGVmaW5lIElFRUU4MDIx MV9WSFRfU1RSRUFNX0dST1VQUwk4IC8qIEJXKD00KSAqIFNHSSg9MikgKi8KKworI2RlZmluZSBJ RUVFODAyMTFfSEVfTUFYX1NUUkVBTVMJOAorI2RlZmluZSBJRUVFODAyMTFfSEVfU1RSRUFNX0dS T1VQUwkxMiAvKiBCVyg9NCkgKiBHSSg9MykgKi8KKworI2RlZmluZSBJRUVFODAyMTFfSFRfR1JP VVBTX05CCShJRUVFODAyMTFfTUFYX1NUUkVBTVMgKglcCisJCQkJIElFRUU4MDIxMV9IVF9TVFJF QU1fR1JPVVBTKQorI2RlZmluZSBJRUVFODAyMTFfVkhUX0dST1VQU19OQgkoSUVFRTgwMjExX01B WF9TVFJFQU1TICoJXAorCQkJCQkgSUVFRTgwMjExX1ZIVF9TVFJFQU1fR1JPVVBTKQorI2RlZmlu ZSBJRUVFODAyMTFfSEVfR1JPVVBTX05CCShJRUVFODAyMTFfSEVfTUFYX1NUUkVBTVMgKglcCisJ CQkJIElFRUU4MDIxMV9IRV9TVFJFQU1fR1JPVVBTKQorI2RlZmluZSBJRUVFODAyMTFfR1JPVVBT X05CCShJRUVFODAyMTFfSFRfR1JPVVBTX05CICsJXAorCQkJCSBJRUVFODAyMTFfVkhUX0dST1VQ U19OQiArCVwKKwkJCQkgSUVFRTgwMjExX0hFX0dST1VQU19OQikKKworI2RlZmluZSBJRUVFODAy MTFfSFRfR1JPVVBfMAkwCisjZGVmaW5lIElFRUU4MDIxMV9WSFRfR1JPVVBfMAkoSUVFRTgwMjEx X0hUX0dST1VQXzAgKyBJRUVFODAyMTFfSFRfR1JPVVBTX05CKQorI2RlZmluZSBJRUVFODAyMTFf SEVfR1JPVVBfMAkoSUVFRTgwMjExX1ZIVF9HUk9VUF8wICsgSUVFRTgwMjExX1ZIVF9HUk9VUFNf TkIpCisKKyNkZWZpbmUgTUNTX0dST1VQX1JBVEVTCQkxMgorCisjZGVmaW5lIEhUX0dST1VQX0lE WChfc3RyZWFtcywgX3NnaSwgX2h0NDApCVwKKwlJRUVFODAyMTFfSFRfR1JPVVBfMCArCQkJXAor CUlFRUU4MDIxMV9NQVhfU1RSRUFNUyAqIDIgKiBfaHQ0MCArCVwKKwlJRUVFODAyMTFfTUFYX1NU UkVBTVMgKiBfc2dpICsJCVwKKwlfc3RyZWFtcyAtIDEKKworI2RlZmluZSBfTUFYKGEsIGIpICgo KGEpPihiKSk/KGEpOihiKSkKKworI2RlZmluZSBHUk9VUF9TSElGVChkdXJhdGlvbikJCQkJCQlc CisJX01BWCgwLCAxNiAtIF9fYnVpbHRpbl9jbHooZHVyYXRpb24pKQorCisvKiBNQ1MgcmF0ZSBp bmZvcm1hdGlvbiBmb3IgYW4gTUNTIGdyb3VwICovCisjZGVmaW5lIF9fTUNTX0dST1VQKF9zdHJl YW1zLCBfc2dpLCBfaHQ0MCwgX3MpCQkJCVwKKwlbSFRfR1JPVVBfSURYKF9zdHJlYW1zLCBfc2dp LCBfaHQ0MCldID0gewkJCVwKKwkuc2hpZnQgPSBfcywJCQkJCQkJXAorCS5kdXJhdGlvbiA9IHsJ CQkJCQkJXAorCQlNQ1NfRFVSQVRJT05fUyhfcywgX3N0cmVhbXMsIF9zZ2ksIF9odDQwID8gNTQg OiAyNiksCVwKKwkJTUNTX0RVUkFUSU9OX1MoX3MsIF9zdHJlYW1zLCBfc2dpLCBfaHQ0MCA/IDEw OCA6IDUyKSwJXAorCQlNQ1NfRFVSQVRJT05fUyhfcywgX3N0cmVhbXMsIF9zZ2ksIF9odDQwID8g MTYyIDogNzgpLAlcCisJCU1DU19EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywgX3NnaSwgX2h0NDAg PyAyMTYgOiAxMDQpLAlcCisJCU1DU19EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywgX3NnaSwgX2h0 NDAgPyAzMjQgOiAxNTYpLAlcCisJCU1DU19EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywgX3NnaSwg X2h0NDAgPyA0MzIgOiAyMDgpLAlcCisJCU1DU19EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywgX3Nn aSwgX2h0NDAgPyA0ODYgOiAyMzQpLAlcCisJCU1DU19EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywg X3NnaSwgX2h0NDAgPyA1NDAgOiAyNjApCVwKKwl9CQkJCQkJCQlcCit9CisKKyNkZWZpbmUgTUNT X0dST1VQX1NISUZUKF9zdHJlYW1zLCBfc2dpLCBfaHQ0MCkJCQkJXAorCUdST1VQX1NISUZUKE1D U19EVVJBVElPTihfc3RyZWFtcywgX3NnaSwgX2h0NDAgPyA1NCA6IDI2KSkKKworI2RlZmluZSBN Q1NfR1JPVVAoX3N0cmVhbXMsIF9zZ2ksIF9odDQwKQkJCQlcCisJX19NQ1NfR1JPVVAoX3N0cmVh bXMsIF9zZ2ksIF9odDQwLAkJCQlcCisJCSAgICBNQ1NfR1JPVVBfU0hJRlQoX3N0cmVhbXMsIF9z Z2ksIF9odDQwKSkKKworI2RlZmluZSBWSFRfR1JPVVBfSURYKF9zdHJlYW1zLCBfc2dpLCBfYncp CQkJCVwKKwkoSUVFRTgwMjExX1ZIVF9HUk9VUF8wICsJCQkJCVwKKwkgSUVFRTgwMjExX01BWF9T VFJFQU1TICogMiAqIChfYncpICsJCQkJXAorCSBJRUVFODAyMTFfTUFYX1NUUkVBTVMgKiAoX3Nn aSkgKwkJCQlcCisJIChfc3RyZWFtcykgLSAxKQorCisjZGVmaW5lIEJXMlZCUFMoX2J3LCByNCwg cjMsIHIyLCByMSkJCQkJCVwKKwkoX2J3ID09IEJXXzE2MCA/IHI0IDogX2J3ID09IEJXXzgwID8g cjMgOiBfYncgPT0gQldfNDAgPyByMiA6IHIxKQorCisjZGVmaW5lIF9fVkhUX0dST1VQKF9zdHJl YW1zLCBfc2dpLCBfYncsIF9zKQkJCQlcCisJW1ZIVF9HUk9VUF9JRFgoX3N0cmVhbXMsIF9zZ2ks IF9idyldID0gewkJCVwKKwkuc2hpZnQgPSBfcywJCQkJCQkJXAorCS5kdXJhdGlvbiA9IHsJCQkJ CQkJXAorCQlNQ1NfRFVSQVRJT05fUyhfcywgX3N0cmVhbXMsIF9zZ2ksCQkJXAorCQkJICAgICAg IEJXMlZCUFMoX2J3LCAgMjM0LCAgMTE3LCAgNTQsICAyNikpLAlcCisJCU1DU19EVVJBVElPTl9T KF9zLCBfc3RyZWFtcywgX3NnaSwJCQlcCisJCQkgICAgICAgQlcyVkJQUyhfYncsICA0NjgsICAy MzQsIDEwOCwgIDUyKSksCVwKKwkJTUNTX0RVUkFUSU9OX1MoX3MsIF9zdHJlYW1zLCBfc2dpLAkJ CVwKKwkJCSAgICAgICBCVzJWQlBTKF9idywgIDcwMiwgIDM1MSwgMTYyLCAgNzgpKSwJXAorCQlN Q1NfRFVSQVRJT05fUyhfcywgX3N0cmVhbXMsIF9zZ2ksCQkJXAorCQkJICAgICAgIEJXMlZCUFMo X2J3LCAgOTM2LCAgNDY4LCAyMTYsIDEwNCkpLAlcCisJCU1DU19EVVJBVElPTl9TKF9zLCBfc3Ry ZWFtcywgX3NnaSwJCQlcCisJCQkgICAgICAgQlcyVkJQUyhfYncsIDE0MDQsICA3MDIsIDMyNCwg MTU2KSksCVwKKwkJTUNTX0RVUkFUSU9OX1MoX3MsIF9zdHJlYW1zLCBfc2dpLAkJCVwKKwkJCSAg ICAgICBCVzJWQlBTKF9idywgMTg3MiwgIDkzNiwgNDMyLCAyMDgpKSwJXAorCQlNQ1NfRFVSQVRJ T05fUyhfcywgX3N0cmVhbXMsIF9zZ2ksCQkJXAorCQkJICAgICAgIEJXMlZCUFMoX2J3LCAyMTA2 LCAxMDUzLCA0ODYsIDIzNCkpLAlcCisJCU1DU19EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywgX3Nn aSwJCQlcCisJCQkgICAgICAgQlcyVkJQUyhfYncsIDIzNDAsIDExNzAsIDU0MCwgMjYwKSksCVwK KwkJTUNTX0RVUkFUSU9OX1MoX3MsIF9zdHJlYW1zLCBfc2dpLAkJCVwKKwkJCSAgICAgICBCVzJW QlBTKF9idywgMjgwOCwgMTQwNCwgNjQ4LCAzMTIpKSwJXAorCQlNQ1NfRFVSQVRJT05fUyhfcywg X3N0cmVhbXMsIF9zZ2ksCQkJXAorCQkJICAgICAgIEJXMlZCUFMoX2J3LCAzMTIwLCAxNTYwLCA3 MjAsIDM0NikpCVwKKyAgICAgICAgfQkJCQkJCQkJXAorfQorCisjZGVmaW5lIFZIVF9HUk9VUF9T SElGVChfc3RyZWFtcywgX3NnaSwgX2J3KQkJCQlcCisJR1JPVVBfU0hJRlQoTUNTX0RVUkFUSU9O KF9zdHJlYW1zLCBfc2dpLAkJCVwKKwkJCQkgQlcyVkJQUyhfYncsIDI0MywgMTE3LCAgNTQsICAy NikpKQorCisjZGVmaW5lIFZIVF9HUk9VUChfc3RyZWFtcywgX3NnaSwgX2J3KQkJCQkJXAorCV9f VkhUX0dST1VQKF9zdHJlYW1zLCBfc2dpLCBfYncsCQkJCVwKKwkJICAgIFZIVF9HUk9VUF9TSElG VChfc3RyZWFtcywgX3NnaSwgX2J3KSkKKworCisjZGVmaW5lIEhFX0dST1VQX0lEWChfc3RyZWFt cywgX2dpLCBfYncpCQkJCVwKKwkoSUVFRTgwMjExX0hFX0dST1VQXzAgKwkJCQkJXAorCSBJRUVF ODAyMTFfSEVfTUFYX1NUUkVBTVMgKiAyICogKF9idykgKwkJCVwKKwkgSUVFRTgwMjExX0hFX01B WF9TVFJFQU1TICogKF9naSkgKwkJCQlcCisJIChfc3RyZWFtcykgLSAxKQorCisjZGVmaW5lIF9f SEVfR1JPVVAoX3N0cmVhbXMsIF9naSwgX2J3LCBfcykJCQkJXAorCVtIRV9HUk9VUF9JRFgoX3N0 cmVhbXMsIF9naSwgX2J3KV0gPSB7CQkJXAorCS5zaGlmdCA9IF9zLAkJCQkJCQlcCisJLmR1cmF0 aW9uID0gewkJCQkJCQlcCisJCUhFX0RVUkFUSU9OX1MoX3MsIF9zdHJlYW1zLCBfZ2ksCQkJXAor CQkJICAgICAgQlcyVkJQUyhfYncsICAgOTc5LCAgNDg5LCAgMjMwLCAgMTE1KSksCVwKKwkJSEVf RFVSQVRJT05fUyhfcywgX3N0cmVhbXMsIF9naSwJCQlcCisJCQkgICAgICBCVzJWQlBTKF9idywg IDE5NTgsICA5NzksICA0NzUsICAyMzApKSwJXAorCQlIRV9EVVJBVElPTl9TKF9zLCBfc3RyZWFt cywgX2dpLAkJCVwKKwkJCSAgICAgIEJXMlZCUFMoX2J3LCAgMjkzNywgMTQ2OCwgIDcwNSwgIDM0 NSkpLAlcCisJCUhFX0RVUkFUSU9OX1MoX3MsIF9zdHJlYW1zLCBfZ2ksCQkJXAorCQkJICAgICAg QlcyVkJQUyhfYncsICAzOTE2LCAxOTU4LCAgOTM2LCAgNDc1KSksCVwKKwkJSEVfRFVSQVRJT05f UyhfcywgX3N0cmVhbXMsIF9naSwJCQlcCisJCQkgICAgICBCVzJWQlBTKF9idywgIDU4NzUsIDI5 MzcsIDE0MTEsICA3MDUpKSwJXAorCQlIRV9EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywgX2dpLAkJ CVwKKwkJCSAgICAgIEJXMlZCUFMoX2J3LCAgNzgzMywgMzkxNiwgMTg3MiwgIDkzNikpLAlcCisJ CUhFX0RVUkFUSU9OX1MoX3MsIF9zdHJlYW1zLCBfZ2ksCQkJXAorCQkJICAgICAgQlcyVkJQUyhf YncsICA4ODI3LCA0NDA2LCAyMTAyLCAxMDUxKSksCVwKKwkJSEVfRFVSQVRJT05fUyhfcywgX3N0 cmVhbXMsIF9naSwJCQlcCisJCQkgICAgICBCVzJWQlBTKF9idywgIDk4MDYsIDQ4OTYsIDIzNDcs IDExNjYpKSwJXAorCQlIRV9EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywgX2dpLAkJCVwKKwkJCSAg ICAgIEJXMlZCUFMoX2J3LCAxMTc2NCwgNTg3NSwgMjgwOCwgMTQxMSkpLAlcCisJCUhFX0RVUkFU SU9OX1MoX3MsIF9zdHJlYW1zLCBfZ2ksCQkJXAorCQkJICAgICAgQlcyVkJQUyhfYncsIDEzMDYw LCA2NTIzLCAzMTI0LCAxNTU1KSksCVwKKwkJSEVfRFVSQVRJT05fUyhfcywgX3N0cmVhbXMsIF9n aSwJCQlcCisJCQkgICAgICBCVzJWQlBTKF9idywgMTQ3MDIsIDczNDQsIDM1MTMsIDE3NTYpKSwJ XAorCQlIRV9EVVJBVElPTl9TKF9zLCBfc3RyZWFtcywgX2dpLAkJCVwKKwkJCSAgICAgIEJXMlZC UFMoX2J3LCAxNjMyOSwgODE2NCwgMzkwMiwgMTk0NCkpCVwKKyAgICAgICAgfQkJCQkJCQkJXAor fQorCisjZGVmaW5lIEhFX0dST1VQX1NISUZUKF9zdHJlYW1zLCBfZ2ksIF9idykJCQkJXAorCUdS T1VQX1NISUZUKEhFX0RVUkFUSU9OKF9zdHJlYW1zLCBfZ2ksCQkJXAorCQkJCUJXMlZCUFMoX2J3 LCAgIDk3OSwgIDQ4OSwgIDIzMCwgIDExNSkpKQorCisjZGVmaW5lIEhFX0dST1VQKF9zdHJlYW1z LCBfZ2ksIF9idykJCQkJCVwKKwlfX0hFX0dST1VQKF9zdHJlYW1zLCBfZ2ksIF9idywJCQkJXAor CQkgICBIRV9HUk9VUF9TSElGVChfc3RyZWFtcywgX2dpLCBfYncpKQorc3RydWN0IG1jc19ncm91 cCB7CisJdTggc2hpZnQ7CisJdTE2IGR1cmF0aW9uW01DU19HUk9VUF9SQVRFU107Cit9OworCitz dGF0aWMgY29uc3Qgc3RydWN0IG1jc19ncm91cCBhaXJ0aW1lX21jc19ncm91cHNbXSA9IHsKKwlN Q1NfR1JPVVAoMSwgMCwgQldfMjApLAorCU1DU19HUk9VUCgyLCAwLCBCV18yMCksCisJTUNTX0dS T1VQKDMsIDAsIEJXXzIwKSwKKwlNQ1NfR1JPVVAoNCwgMCwgQldfMjApLAorCisJTUNTX0dST1VQ KDEsIDEsIEJXXzIwKSwKKwlNQ1NfR1JPVVAoMiwgMSwgQldfMjApLAorCU1DU19HUk9VUCgzLCAx LCBCV18yMCksCisJTUNTX0dST1VQKDQsIDEsIEJXXzIwKSwKKworCU1DU19HUk9VUCgxLCAwLCBC V180MCksCisJTUNTX0dST1VQKDIsIDAsIEJXXzQwKSwKKwlNQ1NfR1JPVVAoMywgMCwgQldfNDAp LAorCU1DU19HUk9VUCg0LCAwLCBCV180MCksCisKKwlNQ1NfR1JPVVAoMSwgMSwgQldfNDApLAor CU1DU19HUk9VUCgyLCAxLCBCV180MCksCisJTUNTX0dST1VQKDMsIDEsIEJXXzQwKSwKKwlNQ1Nf R1JPVVAoNCwgMSwgQldfNDApLAorCisJVkhUX0dST1VQKDEsIDAsIEJXXzIwKSwKKwlWSFRfR1JP VVAoMiwgMCwgQldfMjApLAorCVZIVF9HUk9VUCgzLCAwLCBCV18yMCksCisJVkhUX0dST1VQKDQs IDAsIEJXXzIwKSwKKworCVZIVF9HUk9VUCgxLCAxLCBCV18yMCksCisJVkhUX0dST1VQKDIsIDEs IEJXXzIwKSwKKwlWSFRfR1JPVVAoMywgMSwgQldfMjApLAorCVZIVF9HUk9VUCg0LCAxLCBCV18y MCksCisKKwlWSFRfR1JPVVAoMSwgMCwgQldfNDApLAorCVZIVF9HUk9VUCgyLCAwLCBCV180MCks CisJVkhUX0dST1VQKDMsIDAsIEJXXzQwKSwKKwlWSFRfR1JPVVAoNCwgMCwgQldfNDApLAorCisJ VkhUX0dST1VQKDEsIDEsIEJXXzQwKSwKKwlWSFRfR1JPVVAoMiwgMSwgQldfNDApLAorCVZIVF9H Uk9VUCgzLCAxLCBCV180MCksCisJVkhUX0dST1VQKDQsIDEsIEJXXzQwKSwKKworCVZIVF9HUk9V UCgxLCAwLCBCV184MCksCisJVkhUX0dST1VQKDIsIDAsIEJXXzgwKSwKKwlWSFRfR1JPVVAoMywg MCwgQldfODApLAorCVZIVF9HUk9VUCg0LCAwLCBCV184MCksCisKKwlWSFRfR1JPVVAoMSwgMSwg QldfODApLAorCVZIVF9HUk9VUCgyLCAxLCBCV184MCksCisJVkhUX0dST1VQKDMsIDEsIEJXXzgw KSwKKwlWSFRfR1JPVVAoNCwgMSwgQldfODApLAorCisJVkhUX0dST1VQKDEsIDAsIEJXXzE2MCks CisJVkhUX0dST1VQKDIsIDAsIEJXXzE2MCksCisJVkhUX0dST1VQKDMsIDAsIEJXXzE2MCksCisJ VkhUX0dST1VQKDQsIDAsIEJXXzE2MCksCisKKwlWSFRfR1JPVVAoMSwgMSwgQldfMTYwKSwKKwlW SFRfR1JPVVAoMiwgMSwgQldfMTYwKSwKKwlWSFRfR1JPVVAoMywgMSwgQldfMTYwKSwKKwlWSFRf R1JPVVAoNCwgMSwgQldfMTYwKSwKKworCUhFX0dST1VQKDEsIEhFX0dJXzA4LCBCV18yMCksCisJ SEVfR1JPVVAoMiwgSEVfR0lfMDgsIEJXXzIwKSwKKwlIRV9HUk9VUCgzLCBIRV9HSV8wOCwgQldf MjApLAorCUhFX0dST1VQKDQsIEhFX0dJXzA4LCBCV18yMCksCisJSEVfR1JPVVAoNSwgSEVfR0lf MDgsIEJXXzIwKSwKKwlIRV9HUk9VUCg2LCBIRV9HSV8wOCwgQldfMjApLAorCUhFX0dST1VQKDcs IEhFX0dJXzA4LCBCV18yMCksCisJSEVfR1JPVVAoOCwgSEVfR0lfMDgsIEJXXzIwKSwKKworCUhF X0dST1VQKDEsIEhFX0dJXzE2LCBCV18yMCksCisJSEVfR1JPVVAoMiwgSEVfR0lfMTYsIEJXXzIw KSwKKwlIRV9HUk9VUCgzLCBIRV9HSV8xNiwgQldfMjApLAorCUhFX0dST1VQKDQsIEhFX0dJXzE2 LCBCV18yMCksCisJSEVfR1JPVVAoNSwgSEVfR0lfMTYsIEJXXzIwKSwKKwlIRV9HUk9VUCg2LCBI RV9HSV8xNiwgQldfMjApLAorCUhFX0dST1VQKDcsIEhFX0dJXzE2LCBCV18yMCksCisJSEVfR1JP VVAoOCwgSEVfR0lfMTYsIEJXXzIwKSwKKworCUhFX0dST1VQKDEsIEhFX0dJXzMyLCBCV18yMCks CisJSEVfR1JPVVAoMiwgSEVfR0lfMzIsIEJXXzIwKSwKKwlIRV9HUk9VUCgzLCBIRV9HSV8zMiwg QldfMjApLAorCUhFX0dST1VQKDQsIEhFX0dJXzMyLCBCV18yMCksCisJSEVfR1JPVVAoNSwgSEVf R0lfMzIsIEJXXzIwKSwKKwlIRV9HUk9VUCg2LCBIRV9HSV8zMiwgQldfMjApLAorCUhFX0dST1VQ KDcsIEhFX0dJXzMyLCBCV18yMCksCisJSEVfR1JPVVAoOCwgSEVfR0lfMzIsIEJXXzIwKSwKKwor CUhFX0dST1VQKDEsIEhFX0dJXzA4LCBCV180MCksCisJSEVfR1JPVVAoMiwgSEVfR0lfMDgsIEJX XzQwKSwKKwlIRV9HUk9VUCgzLCBIRV9HSV8wOCwgQldfNDApLAorCUhFX0dST1VQKDQsIEhFX0dJ XzA4LCBCV180MCksCisJSEVfR1JPVVAoNSwgSEVfR0lfMDgsIEJXXzQwKSwKKwlIRV9HUk9VUCg2 LCBIRV9HSV8wOCwgQldfNDApLAorCUhFX0dST1VQKDcsIEhFX0dJXzA4LCBCV180MCksCisJSEVf R1JPVVAoOCwgSEVfR0lfMDgsIEJXXzQwKSwKKworCUhFX0dST1VQKDEsIEhFX0dJXzE2LCBCV180 MCksCisJSEVfR1JPVVAoMiwgSEVfR0lfMTYsIEJXXzQwKSwKKwlIRV9HUk9VUCgzLCBIRV9HSV8x NiwgQldfNDApLAorCUhFX0dST1VQKDQsIEhFX0dJXzE2LCBCV180MCksCisJSEVfR1JPVVAoNSwg SEVfR0lfMTYsIEJXXzQwKSwKKwlIRV9HUk9VUCg2LCBIRV9HSV8xNiwgQldfNDApLAorCUhFX0dS T1VQKDcsIEhFX0dJXzE2LCBCV180MCksCisJSEVfR1JPVVAoOCwgSEVfR0lfMTYsIEJXXzQwKSwK KworCUhFX0dST1VQKDEsIEhFX0dJXzMyLCBCV180MCksCisJSEVfR1JPVVAoMiwgSEVfR0lfMzIs IEJXXzQwKSwKKwlIRV9HUk9VUCgzLCBIRV9HSV8zMiwgQldfNDApLAorCUhFX0dST1VQKDQsIEhF X0dJXzMyLCBCV180MCksCisJSEVfR1JPVVAoNSwgSEVfR0lfMzIsIEJXXzQwKSwKKwlIRV9HUk9V UCg2LCBIRV9HSV8zMiwgQldfNDApLAorCUhFX0dST1VQKDcsIEhFX0dJXzMyLCBCV180MCksCisJ SEVfR1JPVVAoOCwgSEVfR0lfMzIsIEJXXzQwKSwKKworCUhFX0dST1VQKDEsIEhFX0dJXzA4LCBC V184MCksCisJSEVfR1JPVVAoMiwgSEVfR0lfMDgsIEJXXzgwKSwKKwlIRV9HUk9VUCgzLCBIRV9H SV8wOCwgQldfODApLAorCUhFX0dST1VQKDQsIEhFX0dJXzA4LCBCV184MCksCisJSEVfR1JPVVAo NSwgSEVfR0lfMDgsIEJXXzgwKSwKKwlIRV9HUk9VUCg2LCBIRV9HSV8wOCwgQldfODApLAorCUhF X0dST1VQKDcsIEhFX0dJXzA4LCBCV184MCksCisJSEVfR1JPVVAoOCwgSEVfR0lfMDgsIEJXXzgw KSwKKworCUhFX0dST1VQKDEsIEhFX0dJXzE2LCBCV184MCksCisJSEVfR1JPVVAoMiwgSEVfR0lf MTYsIEJXXzgwKSwKKwlIRV9HUk9VUCgzLCBIRV9HSV8xNiwgQldfODApLAorCUhFX0dST1VQKDQs IEhFX0dJXzE2LCBCV184MCksCisJSEVfR1JPVVAoNSwgSEVfR0lfMTYsIEJXXzgwKSwKKwlIRV9H Uk9VUCg2LCBIRV9HSV8xNiwgQldfODApLAorCUhFX0dST1VQKDcsIEhFX0dJXzE2LCBCV184MCks CisJSEVfR1JPVVAoOCwgSEVfR0lfMTYsIEJXXzgwKSwKKworCUhFX0dST1VQKDEsIEhFX0dJXzMy LCBCV184MCksCisJSEVfR1JPVVAoMiwgSEVfR0lfMzIsIEJXXzgwKSwKKwlIRV9HUk9VUCgzLCBI RV9HSV8zMiwgQldfODApLAorCUhFX0dST1VQKDQsIEhFX0dJXzMyLCBCV184MCksCisJSEVfR1JP VVAoNSwgSEVfR0lfMzIsIEJXXzgwKSwKKwlIRV9HUk9VUCg2LCBIRV9HSV8zMiwgQldfODApLAor CUhFX0dST1VQKDcsIEhFX0dJXzMyLCBCV184MCksCisJSEVfR1JPVVAoOCwgSEVfR0lfMzIsIEJX XzgwKSwKKworCUhFX0dST1VQKDEsIEhFX0dJXzA4LCBCV18xNjApLAorCUhFX0dST1VQKDIsIEhF X0dJXzA4LCBCV18xNjApLAorCUhFX0dST1VQKDMsIEhFX0dJXzA4LCBCV18xNjApLAorCUhFX0dS T1VQKDQsIEhFX0dJXzA4LCBCV18xNjApLAorCUhFX0dST1VQKDUsIEhFX0dJXzA4LCBCV18xNjAp LAorCUhFX0dST1VQKDYsIEhFX0dJXzA4LCBCV18xNjApLAorCUhFX0dST1VQKDcsIEhFX0dJXzA4 LCBCV18xNjApLAorCUhFX0dST1VQKDgsIEhFX0dJXzA4LCBCV18xNjApLAorCisJSEVfR1JPVVAo MSwgSEVfR0lfMTYsIEJXXzE2MCksCisJSEVfR1JPVVAoMiwgSEVfR0lfMTYsIEJXXzE2MCksCisJ SEVfR1JPVVAoMywgSEVfR0lfMTYsIEJXXzE2MCksCisJSEVfR1JPVVAoNCwgSEVfR0lfMTYsIEJX XzE2MCksCisJSEVfR1JPVVAoNSwgSEVfR0lfMTYsIEJXXzE2MCksCisJSEVfR1JPVVAoNiwgSEVf R0lfMTYsIEJXXzE2MCksCisJSEVfR1JPVVAoNywgSEVfR0lfMTYsIEJXXzE2MCksCisJSEVfR1JP VVAoOCwgSEVfR0lfMTYsIEJXXzE2MCksCisKKwlIRV9HUk9VUCgxLCBIRV9HSV8zMiwgQldfMTYw KSwKKwlIRV9HUk9VUCgyLCBIRV9HSV8zMiwgQldfMTYwKSwKKwlIRV9HUk9VUCgzLCBIRV9HSV8z MiwgQldfMTYwKSwKKwlIRV9HUk9VUCg0LCBIRV9HSV8zMiwgQldfMTYwKSwKKwlIRV9HUk9VUCg1 LCBIRV9HSV8zMiwgQldfMTYwKSwKKwlIRV9HUk9VUCg2LCBIRV9HSV8zMiwgQldfMTYwKSwKKwlI RV9HUk9VUCg3LCBIRV9HSV8zMiwgQldfMTYwKSwKKwlIRV9HUk9VUCg4LCBIRV9HSV8zMiwgQldf MTYwKSwKK307CisKK3N0YXRpYyB1MzIKK2llZWU4MDIxMV9jYWxjX2xlZ2FjeV9yYXRlX2R1cmF0 aW9uKHUxNiBiaXRyYXRlLCBib29sIHNob3J0X3ByZSwKKwkJCQkgICAgYm9vbCBjY2ssIGludCBs ZW4pCit7CisJdTMyIGR1cmF0aW9uOworCisJaWYgKGNjaykgeworCQlkdXJhdGlvbiA9IDE0NCAr IDQ4OyAvKiBwcmVhbWJsZSArIFBMQ1AgKi8KKwkJaWYgKHNob3J0X3ByZSkKKwkJCWR1cmF0aW9u ID4+PSAxOworCisJCWR1cmF0aW9uICs9IDEwOyAvKiBTSUZTICovCisJfSBlbHNlIHsKKwkJZHVy YXRpb24gPSAyMCArIDE2OyAvKiBwcmVtYWJsZSArIFNJRlMgKi8KKwl9CisKKwlsZW4gPDw9IDM7 CisJZHVyYXRpb24gKz0gKGxlbiAqIDEwKSAvIGJpdHJhdGU7CisKKwlyZXR1cm4gZHVyYXRpb247 Cit9CisKK3UzMiBpZWVlODAyMTFfY2FsY19yeF9haXJ0aW1lKHN0cnVjdCBpZWVlODAyMTFfaHcg Kmh3LAorCQkJICAgICAgc3RydWN0IGllZWU4MDIxMV9yeF9zdGF0dXMgKnN0YXR1cywKKwkJCSAg ICAgIGludCBsZW4pCit7CisJc3RydWN0IGllZWU4MDIxMV9zdXBwb3J0ZWRfYmFuZCAqc2JhbmQ7 CisJY29uc3Qgc3RydWN0IGllZWU4MDIxMV9yYXRlICpyYXRlOworCWJvb2wgc2dpID0gc3RhdHVz LT5lbmNfZmxhZ3MgJiBSWF9FTkNfRkxBR19TSE9SVF9HSTsKKwlib29sIHNwID0gc3RhdHVzLT5l bmNfZmxhZ3MgJiBSWF9FTkNfRkxBR19TSE9SVFBSRTsKKwlpbnQgYncsIHN0cmVhbXM7CisJaW50 IGdyb3VwLCBpZHg7CisJdTMyIGR1cmF0aW9uOworCWJvb2wgY2NrOworCisJc3dpdGNoIChzdGF0 dXMtPmJ3KSB7CisJY2FzZSBSQVRFX0lORk9fQldfMjA6CisJCWJ3ID0gQldfMjA7CisJCWJyZWFr OworCWNhc2UgUkFURV9JTkZPX0JXXzQwOgorCQlidyA9IEJXXzQwOworCQlicmVhazsKKwljYXNl IFJBVEVfSU5GT19CV184MDoKKwkJYncgPSBCV184MDsKKwkJYnJlYWs7CisJY2FzZSBSQVRFX0lO Rk9fQldfMTYwOgorCQlidyA9IEJXXzE2MDsKKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJV0FSTl9P Tl9PTkNFKDEpOworCQlyZXR1cm4gMDsKKwl9CisKKwlzd2l0Y2ggKHN0YXR1cy0+ZW5jb2Rpbmcp IHsKKwljYXNlIFJYX0VOQ19MRUdBQ1k6CisJCWlmIChXQVJOX09OX09OQ0Uoc3RhdHVzLT5iYW5k ID4gTkw4MDIxMV9CQU5EXzVHSFopKQorCQkJcmV0dXJuIDA7CisKKwkJc2JhbmQgPSBody0+d2lw aHktPmJhbmRzW3N0YXR1cy0+YmFuZF07CisJCWlmICghc2JhbmQgfHwgc3RhdHVzLT5yYXRlX2lk eCA+IHNiYW5kLT5uX2JpdHJhdGVzKQorCQkJcmV0dXJuIDA7CisKKwkJcmF0ZSA9ICZzYmFuZC0+ Yml0cmF0ZXNbc3RhdHVzLT5yYXRlX2lkeF07CisJCWNjayA9IHJhdGUtPmZsYWdzICYgSUVFRTgw MjExX1JBVEVfTUFOREFUT1JZX0I7CisKKwkJcmV0dXJuIGllZWU4MDIxMV9jYWxjX2xlZ2FjeV9y YXRlX2R1cmF0aW9uKHJhdGUtPmJpdHJhdGUsIHNwLAorCQkJCQkJCSAgIGNjaywgbGVuKTsKKwor CWNhc2UgUlhfRU5DX1ZIVDoKKwkJc3RyZWFtcyA9IHN0YXR1cy0+bnNzOworCQlpZHggPSBzdGF0 dXMtPnJhdGVfaWR4OworCQlncm91cCA9IFZIVF9HUk9VUF9JRFgoc3RyZWFtcywgc2dpLCBidyk7 CisJCWJyZWFrOworCWNhc2UgUlhfRU5DX0hUOgorCQlzdHJlYW1zID0gKChzdGF0dXMtPnJhdGVf aWR4ID4+IDMpICYgMykgKyAxOworCQlpZHggPSBzdGF0dXMtPnJhdGVfaWR4ICYgNzsKKwkJZ3Jv dXAgPSBIVF9HUk9VUF9JRFgoc3RyZWFtcywgc2dpLCBidyk7CisJCWJyZWFrOworCWNhc2UgUlhf RU5DX0hFOgorCQlzdHJlYW1zID0gc3RhdHVzLT5uc3M7CisJCWlkeCA9IHN0YXR1cy0+cmF0ZV9p ZHg7CisJCWdyb3VwID0gSEVfR1JPVVBfSURYKHN0cmVhbXMsIHN0YXR1cy0+aGVfZ2ksIGJ3KTsK KwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJV0FSTl9PTl9PTkNFKDEpOworCQlyZXR1cm4gMDsKKwl9 CisKKwlpZiAoV0FSTl9PTl9PTkNFKChzdGF0dXMtPmVuY29kaW5nICE9IFJYX0VOQ19IRSAmJiBz dHJlYW1zID4gNCkgfHwKKwkJCSAoc3RhdHVzLT5lbmNvZGluZyA9PSBSWF9FTkNfSEUgJiYgc3Ry ZWFtcyA+IDgpKSkKKwkJcmV0dXJuIDA7CisKKwlkdXJhdGlvbiA9IGFpcnRpbWVfbWNzX2dyb3Vw c1tncm91cF0uZHVyYXRpb25baWR4XTsKKwlkdXJhdGlvbiA8PD0gYWlydGltZV9tY3NfZ3JvdXBz W2dyb3VwXS5zaGlmdDsKKwlkdXJhdGlvbiAqPSBsZW47CisJZHVyYXRpb24gLz0gQVZHX1BLVF9T SVpFOworCWR1cmF0aW9uIC89IDEwMjQ7CisKKwlkdXJhdGlvbiArPSAzNiArIChzdHJlYW1zIDw8 IDIpOworCisJcmV0dXJuIGR1cmF0aW9uOworfQorRVhQT1JUX1NZTUJPTF9HUEwoaWVlZTgwMjEx X2NhbGNfcnhfYWlydGltZSk7CisKK3N0YXRpYyB1MzIgaWVlZTgwMjExX2NhbGNfdHhfYWlydGlt ZV9yYXRlKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LAorCQkJCQkgIHN0cnVjdCBpZWVlODAyMTFf dHhfcmF0ZSAqcmF0ZSwKKwkJCQkJICB1OCBiYW5kLCBpbnQgbGVuKQoreworCXN0cnVjdCBpZWVl ODAyMTFfcnhfc3RhdHVzIHN0YXQgPSB7CisJCS5iYW5kID0gYmFuZCwKKwl9OworCisJaWYgKHJh dGUtPmlkeCA8IDAgfHwgIXJhdGUtPmNvdW50KQorCQlyZXR1cm4gMDsKKworCWlmIChyYXRlLT5m bGFncyAmIElFRUU4MDIxMV9UWF9SQ184MF9NSFpfV0lEVEgpCisJCXN0YXQuYncgPSBSQVRFX0lO Rk9fQldfODA7CisJZWxzZSBpZiAocmF0ZS0+ZmxhZ3MgJiBJRUVFODAyMTFfVFhfUkNfNDBfTUha X1dJRFRIKQorCQlzdGF0LmJ3ID0gUkFURV9JTkZPX0JXXzQwOworCWVsc2UKKwkJc3RhdC5idyA9 IFJBVEVfSU5GT19CV18yMDsKKworCXN0YXQuZW5jX2ZsYWdzID0gMDsKKwlpZiAocmF0ZS0+Zmxh Z3MgJiBJRUVFODAyMTFfVFhfUkNfVVNFX1NIT1JUX1BSRUFNQkxFKQorCQlzdGF0LmVuY19mbGFn cyB8PSBSWF9FTkNfRkxBR19TSE9SVFBSRTsKKwlpZiAocmF0ZS0+ZmxhZ3MgJiBJRUVFODAyMTFf VFhfUkNfU0hPUlRfR0kpCisJCXN0YXQuZW5jX2ZsYWdzIHw9IFJYX0VOQ19GTEFHX1NIT1JUX0dJ OworCisJc3RhdC5yYXRlX2lkeCA9IHJhdGUtPmlkeDsKKwlpZiAocmF0ZS0+ZmxhZ3MgJiBJRUVF ODAyMTFfVFhfUkNfVkhUX01DUykgeworCQlzdGF0LmVuY29kaW5nID0gUlhfRU5DX1ZIVDsKKwkJ c3RhdC5yYXRlX2lkeCA9IGllZWU4MDIxMV9yYXRlX2dldF92aHRfbWNzKHJhdGUpOworCQlzdGF0 Lm5zcyA9IGllZWU4MDIxMV9yYXRlX2dldF92aHRfbnNzKHJhdGUpOworCX0gZWxzZSBpZiAocmF0 ZS0+ZmxhZ3MgJiBJRUVFODAyMTFfVFhfUkNfTUNTKSB7CisJCXN0YXQuZW5jb2RpbmcgPSBSWF9F TkNfSFQ7CisJfSBlbHNlIHsKKwkJc3RhdC5lbmNvZGluZyA9IFJYX0VOQ19MRUdBQ1k7CisJfQor CisJcmV0dXJuIGllZWU4MDIxMV9jYWxjX3J4X2FpcnRpbWUoaHcsICZzdGF0LCBsZW4pOworfQor Cit1MzIgaWVlZTgwMjExX2NhbGNfdHhfYWlydGltZShzdHJ1Y3QgaWVlZTgwMjExX2h3ICpodywK KwkJCSAgICAgIHN0cnVjdCBpZWVlODAyMTFfdHhfaW5mbyAqaW5mbywKKwkJCSAgICAgIGludCBs ZW4pCit7CisJdTMyIGR1cmF0aW9uID0gMDsKKwlpbnQgaTsKKworCWZvciAoaSA9IDA7IGkgPCBB UlJBWV9TSVpFKGluZm8tPnN0YXR1cy5yYXRlcyk7IGkrKykgeworCQlzdHJ1Y3QgaWVlZTgwMjEx X3R4X3JhdGUgKnJhdGUgPSAmaW5mby0+c3RhdHVzLnJhdGVzW2ldOworCQl1MzIgY3VyX2R1cmF0 aW9uOworCisJCWN1cl9kdXJhdGlvbiA9IGllZWU4MDIxMV9jYWxjX3R4X2FpcnRpbWVfcmF0ZSho dywgcmF0ZSwKKwkJCQkJCQkgICAgICBpbmZvLT5iYW5kLCBsZW4pOworCQlpZiAoIWN1cl9kdXJh dGlvbikKKwkJCWJyZWFrOworCisJCWR1cmF0aW9uICs9IGN1cl9kdXJhdGlvbiAqIHJhdGUtPmNv dW50OworCX0KKworCXJldHVybiBkdXJhdGlvbjsKK30KK0VYUE9SVF9TWU1CT0xfR1BMKGllZWU4 MDIxMV9jYWxjX3R4X2FpcnRpbWUpOworCit1MzIgaWVlZTgwMjExX2NhbGNfZXhwZWN0ZWRfdHhf YWlydGltZShzdHJ1Y3QgaWVlZTgwMjExX2h3ICpodywKKwkJCQkgICAgICAgc3RydWN0IGllZWU4 MDIxMV92aWYgKnZpZiwKKwkJCQkgICAgICAgc3RydWN0IGllZWU4MDIxMV9zdGEgKnB1YnN0YSwK KwkJCQkgICAgICAgaW50IGxlbikKK3sKKwlzdHJ1Y3QgaWVlZTgwMjExX3N1cHBvcnRlZF9iYW5k ICpzYmFuZDsKKwlzdHJ1Y3QgaWVlZTgwMjExX2NoYW5jdHhfY29uZiAqY29uZjsKKwlpbnQgcmF0 ZWlkeCwgc2hpZnQgPSAwOworCWJvb2wgY2NrLCBzaG9ydF9wcmVhbTsKKwl1MzIgYmFzaWNfcmF0 ZXM7CisJdTggYmFuZCA9IDA7CisJdTE2IHJhdGU7CisKKwlsZW4gKz0gMzg7IC8qIEV0aGVybmV0 IGhlYWRlciBsZW5ndGggKi8KKworCWNvbmYgPSByY3VfZGVyZWZlcmVuY2UodmlmLT5jaGFuY3R4 X2NvbmYpOworCWlmIChjb25mKSB7CisJCWJhbmQgPSBjb25mLT5kZWYuY2hhbi0+YmFuZDsKKwkJ c2hpZnQgPSBpZWVlODAyMTFfY2hhbmRlZl9nZXRfc2hpZnQoJmNvbmYtPmRlZik7CisJfQorCisJ aWYgKHB1YnN0YSkgeworCQlzdHJ1Y3Qgc3RhX2luZm8gKnN0YSA9IGNvbnRhaW5lcl9vZihwdWJz dGEsIHN0cnVjdCBzdGFfaW5mbywKKwkJCQkJCSAgICBzdGEpOworCisJCXJldHVybiBpZWVlODAy MTFfY2FsY190eF9haXJ0aW1lX3JhdGUoaHcsCisJCQkJCQkgICAgICAmc3RhLT50eF9zdGF0cy5s YXN0X3JhdGUsCisJCQkJCQkgICAgICBiYW5kLCBsZW4pOworCX0KKworCWlmICghY29uZikKKwkJ cmV0dXJuIDA7CisKKwkvKiBObyBzdGF0aW9uIHRvIGdldCBsYXRlc3QgcmF0ZSBmcm9tLCBzbyBj YWxjdWxhdGUgdGhlIHdvcnN0LWNhc2UKKwkgKiBkdXJhdGlvbiB1c2luZyB0aGUgbG93ZXN0IGNv bmZpZ3VyZWQgYmFzaWMgcmF0ZS4KKwkgKi8KKwlzYmFuZCA9IGh3LT53aXBoeS0+YmFuZHNbYmFu ZF07CisKKwliYXNpY19yYXRlcyA9IHZpZi0+YnNzX2NvbmYuYmFzaWNfcmF0ZXM7CisJc2hvcnRf cHJlYW0gPSB2aWYtPmJzc19jb25mLnVzZV9zaG9ydF9wcmVhbWJsZTsKKworCXJhdGVpZHggPSBi YXNpY19yYXRlcyA/IGZmcyhiYXNpY19yYXRlcykgLSAxIDogMDsKKwlyYXRlID0gc2JhbmQtPmJp dHJhdGVzW3JhdGVpZHhdLmJpdHJhdGUgPDwgc2hpZnQ7CisJY2NrID0gc2JhbmQtPmJpdHJhdGVz W3JhdGVpZHhdLmZsYWdzICYgSUVFRTgwMjExX1JBVEVfTUFOREFUT1JZX0I7CisKKwlyZXR1cm4g aWVlZTgwMjExX2NhbGNfbGVnYWN5X3JhdGVfZHVyYXRpb24ocmF0ZSwgc2hvcnRfcHJlYW0sIGNj aywgbGVuKTsKK30KZGlmZiAtLWdpdCBhL25ldC9tYWM4MDIxMS9pZWVlODAyMTFfaS5oIGIvbmV0 L21hYzgwMjExL2llZWU4MDIxMV9pLmgKaW5kZXggMDU0MDZlOWMwNWIzLi4yMjVlYTRlM2NkNzYg MTAwNjQ0Ci0tLSBhL25ldC9tYWM4MDIxMS9pZWVlODAyMTFfaS5oCisrKyBiL25ldC9tYWM4MDIx MS9pZWVlODAyMTFfaS5oCkBAIC0yMjQ5LDYgKzIyNDksMTAgQEAgY29uc3QgY2hhciAqaWVlZTgw MjExX2dldF9yZWFzb25fY29kZV9zdHJpbmcodTE2IHJlYXNvbl9jb2RlKTsKIAogZXh0ZXJuIGNv bnN0IHN0cnVjdCBldGh0b29sX29wcyBpZWVlODAyMTFfZXRodG9vbF9vcHM7CiAKK3UzMiBpZWVl ODAyMTFfY2FsY19leHBlY3RlZF90eF9haXJ0aW1lKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LAor CQkJCSAgICAgICBzdHJ1Y3QgaWVlZTgwMjExX3ZpZiAqdmlmLAorCQkJCSAgICAgICBzdHJ1Y3Qg aWVlZTgwMjExX3N0YSAqcHVic3RhLAorCQkJCSAgICAgICBpbnQgbGVuKTsKICNpZmRlZiBDT05G SUdfTUFDODAyMTFfTk9JTkxJTkUKICNkZWZpbmUgZGVidWdfbm9pbmxpbmUgbm9pbmxpbmUKICNl bHNlCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KYXRo MTBrIG1haWxpbmcgbGlzdAphdGgxMGtAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMu aW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2F0aDEwawo=