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=-12.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT 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 D188EC4363A for ; Mon, 12 Oct 2020 12:56:19 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 600B321D7F for ; Mon, 12 Oct 2020 12:56:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="jzfvGWGn"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="S4pO4Hvx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 600B321D7F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=CwaoZXd2NkT1ZZtXa/GSqUVm7IfYhv1vB3x/BmdSiq0=; b=jzfvGWGnEhtLsR/iWj3vNax8u G6Ml38N2CPrJc+A4VC3o/VckNPz6lSGXciSBvAE7Qg6kOGwXX0ah7h7sgwAMZQo2BHfEtVa2FQtKF Lb9iB1kl6KbAfxomj2MpktiX7pD+xs5Y/8II6/ak+iHLkQozu3MktpY0zXI2HkIy/wxFPCdnnVdCm 54TeLpotg+3gimA5Nbpa1qtz5fWVCHv5pgpSF8MAcSFJERSr7Q+sc/NHM0lLnuDfMPTld32oViOV9 b7Plu6YMC65cGe2dpgNe0s+lkcdsNN010HGQg6e9Z0uYFCAIqf5FPUn2SJqi2Gr+S3ub6i55f4IAs 36QLCH8Mw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kRxN3-0000Il-AK; Mon, 12 Oct 2020 12:56:09 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kRxMy-0000GA-Gp for linux-mediatek@lists.infradead.org; Mon, 12 Oct 2020 12:56:07 +0000 X-UUID: 13e3bc3909c2431d87641dd6d47e23aa-20201012 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=oHWCdpu7EIVJx/y6c7Lyi8a9Pc4aken+nch8nF9lOUM=; b=S4pO4Hvxo3fintuAzTkUxdM/OL4rC+6DUUZdiEQw/ObitX3LKBayxXi5lrTTH0j+PAYuObZXTWtv4TTm/zNXzaVWFh/8fLI0N7UD7/Wa87/IGi4gS/lpYNmgOVCFCwYkYqUJZKMU8MqXr7QBG2+axy8uSoRA+WVrk50wjkhzf7E=; X-UUID: 13e3bc3909c2431d87641dd6d47e23aa-20201012 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 206165599; Mon, 12 Oct 2020 04:56:01 -0800 Received: from MTKMBS06N1.mediatek.inc (172.21.101.129) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 12 Oct 2020 05:55:58 -0700 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs06n1.mediatek.inc (172.21.101.129) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 12 Oct 2020 20:55:58 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Mon, 12 Oct 2020 20:55:56 +0800 From: Shayne Chen To: Felix Fietkau Subject: [PATCH v3 07/10] mt76: mt7915: implement testmode tx support Date: Mon, 12 Oct 2020 20:54:00 +0800 Message-ID: <20201012125403.8608-7-shayne.chen@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20201012125403.8608-1-shayne.chen@mediatek.com> References: <20201012125403.8608-1-shayne.chen@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201012_085604_829647_0B74CFA8 X-CRM114-Status: GOOD ( 20.04 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ryder Lee , Evelyn Tsai , linux-wireless , linux-mediatek , Lorenzo Bianconi , Shayne Chen Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org Support testmode tx for MT7915A, including tx streams and HE rate settings. Reviewed-by: Ryder Lee Signed-off-by: Shayne Chen --- v3: add __packed for req struct in mt7915_tm_mode_ctrl move the location of setting WANT_MONITOR_VIF flag .../wireless/mediatek/mt76/mt7915/Makefile | 2 + .../net/wireless/mediatek/mt76/mt7915/init.c | 8 +- .../net/wireless/mediatek/mt76/mt7915/mac.c | 127 ++++++++++++ .../net/wireless/mediatek/mt76/mt7915/main.c | 40 +++- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 31 +++ .../net/wireless/mediatek/mt76/mt7915/mcu.h | 5 + .../wireless/mediatek/mt76/mt7915/mt7915.h | 14 ++ .../net/wireless/mediatek/mt76/mt7915/regs.h | 31 +++ .../wireless/mediatek/mt76/mt7915/testmode.c | 180 ++++++++++++++++++ .../wireless/mediatek/mt76/mt7915/testmode.h | 34 ++++ 10 files changed, 463 insertions(+), 9 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt7915/testmode.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7915/testmode.h diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/Makefile b/drivers/net/wireless/mediatek/mt76/mt7915/Makefile index 57fe726..cc2054d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt7915/Makefile @@ -4,3 +4,5 @@ obj-$(CONFIG_MT7915E) += mt7915e.o mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \ debugfs.o + +mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index ee69fe4..890c2bb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -270,6 +270,7 @@ mt7915_init_wiphy(struct ieee80211_hw *hw) ieee80211_hw_set(hw, HAS_RATE_CONTROL); ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD); + ieee80211_hw_set(hw, WANT_MONITOR_VIF); hw->max_tx_fragments = 4; } @@ -637,9 +638,6 @@ int mt7915_register_ext_phy(struct mt7915_dev *dev) mphy->hw->wiphy->perm_addr[0] |= 2; mphy->hw->wiphy->perm_addr[0] ^= BIT(7); - /* The second interface does not get any packets unless it has a vif */ - ieee80211_hw_set(mphy->hw, WANT_MONITOR_VIF); - ret = mt76_register_phy(mphy); if (ret) ieee80211_free_hw(mphy->hw); @@ -695,6 +693,10 @@ int mt7915_register_device(struct mt7915_dev *dev) mt7915_cap_dbdc_disable(dev); dev->phy.dfs_state = -1; +#ifdef CONFIG_NL80211_TESTMODE + dev->mt76.test_ops = &mt7915_testmode_ops; +#endif + ret = mt76_register_device(&dev->mt76, true, mt7915_rates, ARRAY_SIZE(mt7915_rates)); if (ret) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index a7118df..e03e12f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -562,6 +562,118 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb) return 0; } +static u16 +mt7915_mac_tx_rate_val(struct mt76_phy *mphy, u8 mode, u8 rate_idx, + u8 nss, u8 stbc, u8 *bw) +{ + u16 rateval; + + switch (mphy->chandef.width) { + case NL80211_CHAN_WIDTH_40: + *bw = 1; + break; + case NL80211_CHAN_WIDTH_80: + *bw = 2; + break; + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + *bw = 3; + break; + default: + *bw = 0; + break; + } + + if (mode == MT_PHY_TYPE_HT || mode == MT_PHY_TYPE_HT_GF) + nss = 1 + (rate_idx >> 3); + + rateval = FIELD_PREP(MT_TX_RATE_IDX, rate_idx) | + FIELD_PREP(MT_TX_RATE_MODE, mode) | + FIELD_PREP(MT_TX_RATE_NSS, nss - 1); + + if (stbc && nss == 1) { + nss++; + rateval |= MT_TX_RATE_STBC; + } + + return rateval; +} + +static void +mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy, + __le32 *txwi, struct sk_buff *skb) +{ +#ifdef CONFIG_NL80211_TESTMODE + struct mt76_testmode_data *td = &dev->mt76.test; + u8 bw, mode; + u16 rateval; + u32 val; + + if (skb != dev->mt76.test.tx_skb) + return; + + switch (td->tx_rate_mode) { + case MT76_TM_TX_MODE_CCK: + mode = MT_PHY_TYPE_CCK; + break; + case MT76_TM_TX_MODE_HT: + mode = MT_PHY_TYPE_HT; + break; + case MT76_TM_TX_MODE_VHT: + mode = MT_PHY_TYPE_VHT; + break; + case MT76_TM_TX_MODE_HE_SU: + mode = MT_PHY_TYPE_HE_SU; + break; + case MT76_TM_TX_MODE_HE_EXT_SU: + mode = MT_PHY_TYPE_HE_EXT_SU; + break; + case MT76_TM_TX_MODE_HE_TB: + mode = MT_PHY_TYPE_HE_TB; + break; + case MT76_TM_TX_MODE_HE_MU: + mode = MT_PHY_TYPE_HE_MU; + break; + case MT76_TM_TX_MODE_OFDM: + default: + mode = MT_PHY_TYPE_OFDM; + break; + } + + rateval = mt7915_mac_tx_rate_val(mphy, mode, td->tx_rate_idx, + td->tx_rate_nss, td->tx_rate_stbc, &bw); + + txwi[2] |= cpu_to_le32(MT_TXD2_FIX_RATE); + if (td->tx_rate_mode < MT76_TM_TX_MODE_HT) + txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); + + val = MT_TXD6_FIXED_BW | + FIELD_PREP(MT_TXD6_BW, bw) | + FIELD_PREP(MT_TXD6_TX_RATE, rateval) | + FIELD_PREP(MT_TXD6_SGI, td->tx_rate_sgi); + + /* for HE_SU/HE_EXT_SU PPDU + * - 1x, 2x, 4x LTF + 0.8us GI + * - 2x LTF + 1.6us GI, 4x LTF + 3.2us GI + * for HE_MU PPDU + * - 2x, 4x LTF + 0.8us GI + * - 2x LTF + 1.6us GI, 4x LTF + 3.2us GI + * for HE_TB PPDU + * - 1x, 2x LTF + 1.6us GI + * - 4x LTF + 3.2us GI + */ + if (mode >= MT_PHY_TYPE_HE_SU) + val |= FIELD_PREP(MT_TXD6_HELTF, td->tx_ltf); + + if (td->tx_rate_ldpc) + val |= MT_TXD6_LDPC; + + txwi[6] |= cpu_to_le32(val); + txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, + dev->test.spe_idx)); +#endif +} + static void mt7915_mac_write_txwi_8023(struct mt7915_dev *dev, __le32 *txwi, struct sk_buff *skb, struct mt76_wcid *wcid) @@ -761,6 +873,9 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, txwi[6] |= cpu_to_le32(val); txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); } + + if (mt76_testmode_enabled(&dev->mt76)) + mt7915_mac_write_txwi_tm(dev, mphy, txwi, skb); } int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, @@ -881,6 +996,18 @@ mt7915_tx_complete_status(struct mt76_dev *mdev, struct sk_buff *skb, hw = mt76_tx_status_get_hw(mdev, skb); +#ifdef CONFIG_NL80211_TESTMODE + if (skb == mdev->test.tx_skb) { + struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct ieee80211_vif *vif = phy->monitor_vif; + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + + mt76_tx_complete_skb(mdev, mvif->sta.wcid.idx, skb); + + return; + } +#endif + if (info->flags & IEEE80211_TX_CTL_AMPDU) info->flags |= IEEE80211_TX_STAT_AMPDU; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 1262fb3..9ebe5af 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -44,13 +44,14 @@ static int mt7915_start(struct ieee80211_hw *hw) mt7915_mac_enable_nf(dev, 1); } - mt7915_mcu_set_sku_en(phy, true); + mt7915_mcu_set_sku_en(phy, !mt76_testmode_enabled(&dev->mt76)); mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH); set_bit(MT76_STATE_RUNNING, &phy->mt76->state); - ieee80211_queue_delayed_work(hw, &phy->mac_work, - MT7915_WATCHDOG_TIME); + if (!mt76_testmode_enabled(&dev->mt76)) + ieee80211_queue_delayed_work(hw, &phy->mac_work, + MT7915_WATCHDOG_TIME); if (!running) mt7915_mac_reset_counters(phy); @@ -69,6 +70,8 @@ static void mt7915_stop(struct ieee80211_hw *hw) mutex_lock(&dev->mt76.mutex); + mt76_testmode_reset(&dev->mt76, true); + clear_bit(MT76_STATE_RUNNING, &phy->mt76->state); if (phy != &dev->phy) { @@ -150,6 +153,12 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, mutex_lock(&dev->mt76.mutex); + mt76_testmode_reset(&dev->mt76, true); + + if (vif->type == NL80211_IFTYPE_MONITOR && + is_zero_ether_addr(vif->addr)) + phy->monitor_vif = vif; + mvif->idx = ffs(~phy->mt76->vif_mask) - 1; if (mvif->idx >= MT7915_MAX_INTERFACES) { ret = -ENOSPC; @@ -218,6 +227,13 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw, /* TODO: disable beacon for the bss */ + mutex_lock(&dev->mt76.mutex); + mt76_testmode_reset(&dev->mt76, true); + mutex_unlock(&dev->mt76.mutex); + + if (vif == phy->monitor_vif) + phy->monitor_vif = NULL; + mt7915_mcu_add_dev_info(phy, vif, false); rcu_assign_pointer(dev->mt76.wcid[idx], NULL); @@ -252,7 +268,7 @@ static void mt7915_init_dfs_state(struct mt7915_phy *phy) phy->dfs_state = -1; } -static int mt7915_set_channel(struct mt7915_phy *phy) +int mt7915_set_channel(struct mt7915_phy *phy) { struct mt7915_dev *dev = phy->dev; int ret; @@ -281,8 +297,10 @@ out: mutex_unlock(&dev->mt76.mutex); mt76_txq_schedule_all(phy->mt76); - ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work, - MT7915_WATCHDOG_TIME); + + if (!mt76_testmode_enabled(&dev->mt76)) + ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work, + MT7915_WATCHDOG_TIME); return ret; } @@ -346,6 +364,13 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) int ret; if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { +#ifdef CONFIG_NL80211_TESTMODE + if (dev->mt76.test.state != MT76_TM_STATE_OFF) { + mutex_lock(&dev->mt76.mutex); + mt76_testmode_reset(&dev->mt76, false); + mutex_unlock(&dev->mt76.mutex); + } +#endif ieee80211_stop_queues(hw); ret = mt7915_set_channel(phy); if (ret) @@ -370,6 +395,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC; mt76_rmw_field(dev, MT_DMA_DCR0, MT_DMA_DCR0_RXD_G5_EN, enabled); + mt76_testmode_reset(&dev->mt76, true); mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter); } @@ -887,6 +913,8 @@ const struct ieee80211_ops mt7915_ops = { .set_coverage_class = mt7915_set_coverage_class, .sta_statistics = mt7915_sta_statistics, .sta_set_4addr = mt7915_sta_set_4addr, + CFG80211_TESTMODE_CMD(mt76_testmode_cmd) + CFG80211_TESTMODE_DUMP(mt76_testmode_dump) #ifdef CONFIG_MAC80211_DEBUGFS .sta_add_debugfs = mt7915_sta_add_debugfs, #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 5ccde54..372f45b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -3186,6 +3186,15 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) .channel_band = chandef->chan->band, }; +#ifdef CONFIG_NL80211_TESTMODE + if (dev->mt76.test.tx_antenna_mask && + (dev->mt76.test.state == MT76_TM_STATE_TX_FRAMES || + dev->mt76.test.state == MT76_TM_STATE_RX_FRAMES)) { + req.tx_streams_num = fls(dev->mt76.test.tx_antenna_mask); + req.rx_streams = dev->mt76.test.tx_antenna_mask; + } +#endif + if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD; else if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) && @@ -3330,6 +3339,28 @@ int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy) sizeof(req), true); } +int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode, + u8 en) +{ + struct { + u8 test_mode_en; + u8 param_idx; + u8 _rsv[2]; + + u8 enable; + u8 _rsv2[3]; + + u8 pad[8]; + } __packed req = { + .test_mode_en = test_mode, + .param_idx = param, + .enable = en, + }; + + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req, + sizeof(req), false); +} + int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable) { struct mt7915_dev *dev = phy->dev; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index 5f23f27..0a7e9d2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -46,6 +46,10 @@ enum { MCU_EXT_EVENT_RATE_REPORT = 0x87, }; +enum { + MCU_ATE_SET_TRX = 0x1, +}; + struct mt7915_mcu_rxd { __le32 rxd[6]; @@ -216,6 +220,7 @@ enum { MCU_EXT_CMD_WTBL_UPDATE = 0x32, MCU_EXT_CMD_SET_DRR_CTRL = 0x36, MCU_EXT_CMD_SET_RDD_CTRL = 0x3a, + MCU_EXT_CMD_ATE_CTRL = 0x3d, MCU_EXT_CMD_PROTECT_CTRL = 0x3e, MCU_EXT_CMD_MAC_INIT_CTRL = 0x46, MCU_EXT_CMD_RX_HDR_TRANS = 0x47, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 4292153..6735915 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -108,6 +108,8 @@ struct mt7915_phy { struct ieee80211_sband_iftype_data iftype[2][NUM_NL80211_IFTYPES]; + struct ieee80211_vif *monitor_vif; + u32 rxfilter; u64 omac_mask; @@ -158,6 +160,14 @@ struct mt7915_dev { struct idr token; bool fw_debug; + +#ifdef CONFIG_NL80211_TESTMODE + struct { + u32 *reg_backup; + + u8 spe_idx; + } test; +#endif }; enum { @@ -247,6 +257,7 @@ static inline u8 mt7915_lmac_mapping(struct mt7915_dev *dev, u8 ac) extern const struct ieee80211_ops mt7915_ops; extern struct pci_driver mt7915_pci_driver; +extern const struct mt76_testmode_ops mt7915_testmode_ops; u32 mt7915_reg_map(struct mt7915_dev *dev, u32 addr); @@ -292,6 +303,7 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +int mt7915_set_channel(struct mt7915_phy *phy); int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd); int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif); int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev, @@ -300,6 +312,8 @@ int mt7915_mcu_set_eeprom(struct mt7915_dev *dev); int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset); int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, bool hdr_trans); +int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode, + u8 en); int mt7915_mcu_set_scs(struct mt7915_dev *dev, u8 band, bool enable); int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band); int mt7915_mcu_set_rts_thresh(struct mt7915_phy *phy, u32 val); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h index e4252c8..503c9c8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h @@ -51,6 +51,9 @@ #define MT_WF_TMAC_BASE(_band) ((_band) ? 0xa1000 : 0x21000) #define MT_WF_TMAC(_band, ofs) (MT_WF_TMAC_BASE(_band) + (ofs)) +#define MT_TMAC_TCR0(_band) MT_WF_TMAC(_band, 0) +#define MT_TMAC_TCR0_TBTT_STOP_CTRL BIT(25) + #define MT_TMAC_CDTR(_band) MT_WF_TMAC(_band, 0x090) #define MT_TMAC_ODTR(_band) MT_WF_TMAC(_band, 0x094) #define MT_TIMEOUT_VAL_PLCP GENMASK(15, 0) @@ -72,6 +75,9 @@ #define MT_TMAC_FP0R18(_band) MT_WF_TMAC(_band, 0x270) #define MT_TMAC_FP_MASK GENMASK(7, 0) +#define MT_TMAC_TRCR0(_band) MT_WF_TMAC(_band, 0x09c) +#define MT_TMAC_TFCR0(_band) MT_WF_TMAC(_band, 0x1e0) + /* DMA Band 0 */ #define MT_WF_DMA_BASE 0x21e00 #define MT_WF_DMA(ofs) (MT_WF_DMA_BASE + (ofs)) @@ -171,10 +177,33 @@ #define MT_WF_AGG_BASE(_band) ((_band) ? 0xa0800 : 0x20800) #define MT_WF_AGG(_band, ofs) (MT_WF_AGG_BASE(_band) + (ofs)) +#define MT_AGG_AWSCR0(_band, _n) MT_WF_AGG(_band, 0x05c + (_n) * 4) +#define MT_AGG_PCR0(_band, _n) MT_WF_AGG(_band, 0x06c + (_n) * 4) +#define MT_AGG_PCR0_MM_PROT BIT(0) +#define MT_AGG_PCR0_GF_PROT BIT(1) +#define MT_AGG_PCR0_BW20_PROT BIT(2) +#define MT_AGG_PCR0_BW40_PROT BIT(4) +#define MT_AGG_PCR0_BW80_PROT BIT(6) +#define MT_AGG_PCR0_ERP_PROT GENMASK(12, 8) +#define MT_AGG_PCR0_VHT_PROT BIT(13) +#define MT_AGG_PCR0_PTA_WIN_DIS BIT(15) + +#define MT_AGG_PCR1_RTS0_NUM_THRES GENMASK(31, 23) +#define MT_AGG_PCR1_RTS0_LEN_THRES GENMASK(19, 0) + #define MT_AGG_ACR0(_band) MT_WF_AGG(_band, 0x084) #define MT_AGG_ACR_CFEND_RATE GENMASK(13, 0) #define MT_AGG_ACR_BAR_RATE GENMASK(29, 16) +#define MT_AGG_MRCR(_band) MT_WF_AGG(_band, 0x098) +#define MT_AGG_MRCR_BAR_CNT_LIMIT GENMASK(15, 12) +#define MT_AGG_MRCR_LAST_RTS_CTS_RN BIT(6) +#define MT_AGG_MRCR_RTS_FAIL_LIMIT GENMASK(11, 7) +#define MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT GENMASK(28, 24) + +#define MT_AGG_ATCR1(_band) MT_WF_AGG(_band, 0x0f0) +#define MT_AGG_ATCR3(_band) MT_WF_AGG(_band, 0x0f4) + /* ARB: band 0(0x20c00), band 1(0xa0c00) */ #define MT_WF_ARB_BASE(_band) ((_band) ? 0xa0c00 : 0x20c00) #define MT_WF_ARB(_band, ofs) (MT_WF_ARB_BASE(_band) + (ofs)) @@ -183,6 +212,8 @@ #define MT_ARB_SCR_TX_DISABLE BIT(8) #define MT_ARB_SCR_RX_DISABLE BIT(9) +#define MT_ARB_DRNGR0(_band, _n) MT_WF_ARB(_band, 0x194 + (_n) * 4) + /* RMAC: band 0(0x21400), band 1(0xa1400) */ #define MT_WF_RMAC_BASE(_band) ((_band) ? 0xa1400 : 0x21400) #define MT_WF_RMAC(_band, ofs) (MT_WF_RMAC_BASE(_band) + (ofs)) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c new file mode 100644 index 0000000..5d95766 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2020 MediaTek Inc. */ + +#include "mt7915.h" +#include "mac.h" +#include "mcu.h" +#include "testmode.h" + +struct reg_band { + u32 band[2]; +}; + +#define REG_BAND(_reg) \ + { .band[0] = MT_##_reg(0), .band[1] = MT_##_reg(1) } +#define REG_BAND_IDX(_reg, _idx) \ + { .band[0] = MT_##_reg(0, _idx), .band[1] = MT_##_reg(1, _idx) } + +static const struct reg_band reg_backup_list[] = { + REG_BAND_IDX(AGG_PCR0, 0), + REG_BAND_IDX(AGG_PCR0, 1), + REG_BAND_IDX(AGG_AWSCR0, 0), + REG_BAND_IDX(AGG_AWSCR0, 1), + REG_BAND_IDX(AGG_AWSCR0, 2), + REG_BAND_IDX(AGG_AWSCR0, 3), + REG_BAND(AGG_MRCR), + REG_BAND(TMAC_TFCR0), + REG_BAND(TMAC_TCR0), + REG_BAND(AGG_ATCR1), + REG_BAND(AGG_ATCR3), + REG_BAND(TMAC_TRCR0), + REG_BAND(TMAC_ICR0), + REG_BAND_IDX(ARB_DRNGR0, 0), + REG_BAND_IDX(ARB_DRNGR0, 1), +}; + +static int +mt7915_tm_mode_ctrl(struct mt7915_dev *dev, bool enable) +{ + struct { + u8 format_id; + bool enable; + u8 rsv[2]; + } __packed req = { + .format_id = 0x6, + .enable = enable, + }; + + return mt76_mcu_send_msg(&dev->mt76, + MCU_EXT_CMD_TX_POWER_FEATURE_CTRL, + &req, sizeof(req), false); +} + +static int +mt7915_tm_set_trx(struct mt7915_dev *dev, struct mt7915_phy *phy, + int type, bool en) +{ + struct mt7915_tm_cmd req = { + .testmode_en = 1, + .param_idx = MCU_ATE_SET_TRX, + .param.trx.type = type, + .param.trx.enable = en, + .param.trx.band = phy != &dev->phy, + }; + + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req, + sizeof(req), false); +} + +static void +mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy) +{ + int n_regs = ARRAY_SIZE(reg_backup_list); + bool ext_phy = phy != &dev->phy; + u32 *b = dev->test.reg_backup; + int i; + + if (dev->mt76.test.state == MT76_TM_STATE_OFF) { + for (i = 0; i < n_regs; i++) + mt76_wr(dev, reg_backup_list[i].band[ext_phy], b[i]); + return; + } + + if (b) + return; + + b = devm_kzalloc(dev->mt76.dev, 4 * n_regs, GFP_KERNEL); + if (!b) + return; + + dev->test.reg_backup = b; + for (i = 0; i < n_regs; i++) + b[i] = mt76_rr(dev, reg_backup_list[i].band[ext_phy]); + + mt76_clear(dev, MT_AGG_PCR0(ext_phy, 0), MT_AGG_PCR0_MM_PROT | + MT_AGG_PCR0_GF_PROT | MT_AGG_PCR0_ERP_PROT | + MT_AGG_PCR0_VHT_PROT | MT_AGG_PCR0_BW20_PROT | + MT_AGG_PCR0_BW40_PROT | MT_AGG_PCR0_BW80_PROT); + mt76_set(dev, MT_AGG_PCR0(ext_phy, 0), MT_AGG_PCR0_PTA_WIN_DIS); + + mt76_wr(dev, MT_AGG_PCR0(ext_phy, 1), MT_AGG_PCR1_RTS0_NUM_THRES | + MT_AGG_PCR1_RTS0_LEN_THRES); + + mt76_clear(dev, MT_AGG_MRCR(0), MT_AGG_MRCR_BAR_CNT_LIMIT | + MT_AGG_MRCR_LAST_RTS_CTS_RN | MT_AGG_MRCR_RTS_FAIL_LIMIT | + MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT); + + mt76_rmw(dev, MT_AGG_MRCR(0), MT_AGG_MRCR_RTS_FAIL_LIMIT | + MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, + FIELD_PREP(MT_AGG_MRCR_RTS_FAIL_LIMIT, 1) | + FIELD_PREP(MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, 1)); + + mt76_wr(dev, MT_TMAC_TFCR0(0), 0); + mt76_clear(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TBTT_STOP_CTRL); +} + +static void +mt7915_tm_init(struct mt7915_dev *dev) +{ + bool en = !(dev->mt76.test.state == MT76_TM_STATE_OFF); + + if (!test_bit(MT76_STATE_RUNNING, &dev->phy.mt76->state)) + return; + + mt7915_tm_mode_ctrl(dev, en); + mt7915_tm_reg_backup_restore(dev, &dev->phy); + mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TXRX, !en); +} + +static void +mt7915_tm_set_tx_frames(struct mt7915_dev *dev, bool en) +{ + static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0, + 9, 8, 6, 10, 16, 12, 18, 0}; + struct sk_buff *skb = dev->mt76.test.tx_skb; + struct ieee80211_tx_info *info; + + mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_RX_RXV, false); + + if (en) { + u8 tx_ant = dev->mt76.test.tx_antenna_mask; + + mutex_unlock(&dev->mt76.mutex); + mt7915_set_channel(&dev->phy); + mutex_lock(&dev->mt76.mutex); + + mt7915_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH); + dev->test.spe_idx = spe_idx_map[tx_ant]; + } + + mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TX, en); + + if (!en || !skb) + return; + + info = IEEE80211_SKB_CB(skb); + info->control.vif = dev->phy.monitor_vif; +} + +static int +mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state) +{ + struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); + struct mt76_testmode_data *td = &mdev->test; + enum mt76_testmode_state prev_state = td->state; + + mdev->test.state = state; + + if (prev_state == MT76_TM_STATE_TX_FRAMES) + mt7915_tm_set_tx_frames(dev, false); + else if (state == MT76_TM_STATE_TX_FRAMES) + mt7915_tm_set_tx_frames(dev, true); + else if (prev_state == MT76_TM_STATE_OFF || state == MT76_TM_STATE_OFF) + mt7915_tm_init(dev); + + return 0; +} + +const struct mt76_testmode_ops mt7915_testmode_ops = { + .set_state = mt7915_tm_set_state, +}; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h new file mode 100644 index 0000000..04f4a2c --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2020 MediaTek Inc. */ + +#ifndef __MT7915_TESTMODE_H +#define __MT7915_TESTMODE_H + +struct mt7915_tm_trx { + u8 type; + u8 enable; + u8 band; + u8 rsv; +}; + +struct mt7915_tm_cmd { + u8 testmode_en; + u8 param_idx; + u8 _rsv[2]; + union { + __le32 data; + struct mt7915_tm_trx trx; + u8 test[72]; + } param; +} __packed; + +enum { + TM_MAC_TX = 1, + TM_MAC_RX, + TM_MAC_TXRX, + TM_MAC_TXRX_RXV, + TM_MAC_RXV, + TM_MAC_RX_RXV, +}; + +#endif -- 2.17.1 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek 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=-11.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_GIT 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 587E8C4363A for ; Mon, 12 Oct 2020 12:56:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 141EE221EB for ; Mon, 12 Oct 2020 12:56:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="sWZ5IzbX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730272AbgJLM4a (ORCPT ); Mon, 12 Oct 2020 08:56:30 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:53196 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1730235AbgJLM4U (ORCPT ); Mon, 12 Oct 2020 08:56:20 -0400 X-UUID: 9326c940004f40529f208a9bfa2a7da6-20201012 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=oHWCdpu7EIVJx/y6c7Lyi8a9Pc4aken+nch8nF9lOUM=; b=sWZ5IzbXD/xw5aKHnpYz4buIEhFOXHhiCLZGiLGamkkUIlwC2Md8oBUQE/xmbA7xPPdCBPMpqQN4E/oMzDTkMHCd4Cyu4rZ6gjqibOIhR3sugLNZ3iIZkDs7TuS1YtLphOsSrcv0SOlRCMG3RA45xpGXLQi6TFUJ/qzt6GGkHzI=; X-UUID: 9326c940004f40529f208a9bfa2a7da6-20201012 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.14 Build 0819 with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 639034662; Mon, 12 Oct 2020 20:55:59 +0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs06n1.mediatek.inc (172.21.101.129) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 12 Oct 2020 20:55:58 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Mon, 12 Oct 2020 20:55:56 +0800 From: Shayne Chen To: Felix Fietkau CC: linux-wireless , Lorenzo Bianconi , Ryder Lee , Evelyn Tsai , linux-mediatek , Shayne Chen Subject: [PATCH v3 07/10] mt76: mt7915: implement testmode tx support Date: Mon, 12 Oct 2020 20:54:00 +0800 Message-ID: <20201012125403.8608-7-shayne.chen@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20201012125403.8608-1-shayne.chen@mediatek.com> References: <20201012125403.8608-1-shayne.chen@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Content-Transfer-Encoding: base64 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org U3VwcG9ydCB0ZXN0bW9kZSB0eCBmb3IgTVQ3OTE1QSwgaW5jbHVkaW5nIHR4IHN0cmVhbXMgYW5k IEhFIHJhdGUNCnNldHRpbmdzLg0KDQpSZXZpZXdlZC1ieTogUnlkZXIgTGVlIDxyeWRlci5sZWVA bWVkaWF0ZWsuY29tPg0KU2lnbmVkLW9mZi1ieTogU2hheW5lIENoZW4gPHNoYXluZS5jaGVuQG1l ZGlhdGVrLmNvbT4NCi0tLQ0KdjM6IGFkZCBfX3BhY2tlZCBmb3IgcmVxIHN0cnVjdCBpbiBtdDc5 MTVfdG1fbW9kZV9jdHJsDQogICAgbW92ZSB0aGUgbG9jYXRpb24gb2Ygc2V0dGluZyBXQU5UX01P TklUT1JfVklGIGZsYWcNCg0KIC4uLi93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9NYWtl ZmlsZSAgICB8ICAgMiArDQogLi4uL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9p bml0LmMgIHwgICA4ICstDQogLi4uL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9t YWMuYyAgIHwgMTI3ICsrKysrKysrKysrKw0KIC4uLi9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3 Ni9tdDc5MTUvbWFpbi5jICB8ICA0MCArKystDQogLi4uL25ldC93aXJlbGVzcy9tZWRpYXRlay9t dDc2L210NzkxNS9tY3UuYyAgIHwgIDMxICsrKw0KIC4uLi9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsv bXQ3Ni9tdDc5MTUvbWN1LmggICB8ICAgNSArDQogLi4uL3dpcmVsZXNzL21lZGlhdGVrL210NzYv bXQ3OTE1L210NzkxNS5oICAgIHwgIDE0ICsrDQogLi4uL25ldC93aXJlbGVzcy9tZWRpYXRlay9t dDc2L210NzkxNS9yZWdzLmggIHwgIDMxICsrKw0KIC4uLi93aXJlbGVzcy9tZWRpYXRlay9tdDc2 L210NzkxNS90ZXN0bW9kZS5jICB8IDE4MCArKysrKysrKysrKysrKysrKysNCiAuLi4vd2lyZWxl c3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvdGVzdG1vZGUuaCAgfCAgMzQgKysrKw0KIDEwIGZpbGVz IGNoYW5nZWQsIDQ2MyBpbnNlcnRpb25zKCspLCA5IGRlbGV0aW9ucygtKQ0KIGNyZWF0ZSBtb2Rl IDEwMDY0NCBkcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS90ZXN0bW9k ZS5jDQogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210 NzYvbXQ3OTE1L3Rlc3Rtb2RlLmgNCg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNz L21lZGlhdGVrL210NzYvbXQ3OTE1L01ha2VmaWxlIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVk aWF0ZWsvbXQ3Ni9tdDc5MTUvTWFrZWZpbGUNCmluZGV4IDU3ZmU3MjYuLmNjMjA1NGQgMTAwNjQ0 DQotLS0gYS9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9NYWtlZmls ZQ0KKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvTWFrZWZp bGUNCkBAIC00LDMgKzQsNSBAQCBvYmotJChDT05GSUdfTVQ3OTE1RSkgKz0gbXQ3OTE1ZS5vDQog DQogbXQ3OTE1ZS15IDo9IHBjaS5vIGluaXQubyBkbWEubyBlZXByb20ubyBtYWluLm8gbWN1Lm8g bWFjLm8gXA0KIAkgICAgIGRlYnVnZnMubw0KKw0KK210NzkxNWUtJChDT05GSUdfTkw4MDIxMV9U RVNUTU9ERSkgKz0gdGVzdG1vZGUubw0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNz L21lZGlhdGVrL210NzYvbXQ3OTE1L2luaXQuYyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlh dGVrL210NzYvbXQ3OTE1L2luaXQuYw0KaW5kZXggZWU2OWZlNC4uODkwYzJiYiAxMDA2NDQNCi0t LSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L2luaXQuYw0KKysr IGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvaW5pdC5jDQpAQCAt MjcwLDYgKzI3MCw3IEBAIG10NzkxNV9pbml0X3dpcGh5KHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3 KQ0KIA0KIAlpZWVlODAyMTFfaHdfc2V0KGh3LCBIQVNfUkFURV9DT05UUk9MKTsNCiAJaWVlZTgw MjExX2h3X3NldChodywgU1VQUE9SVFNfVFhfRU5DQVBfT0ZGTE9BRCk7DQorCWllZWU4MDIxMV9o d19zZXQoaHcsIFdBTlRfTU9OSVRPUl9WSUYpOw0KIA0KIAlody0+bWF4X3R4X2ZyYWdtZW50cyA9 IDQ7DQogfQ0KQEAgLTYzNyw5ICs2MzgsNiBAQCBpbnQgbXQ3OTE1X3JlZ2lzdGVyX2V4dF9waHko c3RydWN0IG10NzkxNV9kZXYgKmRldikNCiAJbXBoeS0+aHctPndpcGh5LT5wZXJtX2FkZHJbMF0g fD0gMjsNCiAJbXBoeS0+aHctPndpcGh5LT5wZXJtX2FkZHJbMF0gXj0gQklUKDcpOw0KIA0KLQkv KiBUaGUgc2Vjb25kIGludGVyZmFjZSBkb2VzIG5vdCBnZXQgYW55IHBhY2tldHMgdW5sZXNzIGl0 IGhhcyBhIHZpZiAqLw0KLQlpZWVlODAyMTFfaHdfc2V0KG1waHktPmh3LCBXQU5UX01PTklUT1Jf VklGKTsNCi0NCiAJcmV0ID0gbXQ3Nl9yZWdpc3Rlcl9waHkobXBoeSk7DQogCWlmIChyZXQpDQog CQlpZWVlODAyMTFfZnJlZV9odyhtcGh5LT5odyk7DQpAQCAtNjk1LDYgKzY5MywxMCBAQCBpbnQg bXQ3OTE1X3JlZ2lzdGVyX2RldmljZShzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2KQ0KIAltdDc5MTVf Y2FwX2RiZGNfZGlzYWJsZShkZXYpOw0KIAlkZXYtPnBoeS5kZnNfc3RhdGUgPSAtMTsNCiANCisj aWZkZWYgQ09ORklHX05MODAyMTFfVEVTVE1PREUNCisJZGV2LT5tdDc2LnRlc3Rfb3BzID0gJm10 NzkxNV90ZXN0bW9kZV9vcHM7DQorI2VuZGlmDQorDQogCXJldCA9IG10NzZfcmVnaXN0ZXJfZGV2 aWNlKCZkZXYtPm10NzYsIHRydWUsIG10NzkxNV9yYXRlcywNCiAJCQkJICAgQVJSQVlfU0laRSht dDc5MTVfcmF0ZXMpKTsNCiAJaWYgKHJldCkNCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJl bGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9tYWMuYyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21l ZGlhdGVrL210NzYvbXQ3OTE1L21hYy5jDQppbmRleCBhNzExOGRmLi5lMDNlMTJmIDEwMDY0NA0K LS0tIGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbWFjLmMNCisr KyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L21hYy5jDQpAQCAt NTYyLDYgKzU2MiwxMTggQEAgaW50IG10NzkxNV9tYWNfZmlsbF9yeChzdHJ1Y3QgbXQ3OTE1X2Rl diAqZGV2LCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQ0KIAlyZXR1cm4gMDsNCiB9DQogDQorc3RhdGlj IHUxNg0KK210NzkxNV9tYWNfdHhfcmF0ZV92YWwoc3RydWN0IG10NzZfcGh5ICptcGh5LCB1OCBt b2RlLCB1OCByYXRlX2lkeCwNCisJCSAgICAgICB1OCBuc3MsIHU4IHN0YmMsIHU4ICpidykNCit7 DQorCXUxNiByYXRldmFsOw0KKw0KKwlzd2l0Y2ggKG1waHktPmNoYW5kZWYud2lkdGgpIHsNCisJ Y2FzZSBOTDgwMjExX0NIQU5fV0lEVEhfNDA6DQorCQkqYncgPSAxOw0KKwkJYnJlYWs7DQorCWNh c2UgTkw4MDIxMV9DSEFOX1dJRFRIXzgwOg0KKwkJKmJ3ID0gMjsNCisJCWJyZWFrOw0KKwljYXNl IE5MODAyMTFfQ0hBTl9XSURUSF84MFA4MDoNCisJY2FzZSBOTDgwMjExX0NIQU5fV0lEVEhfMTYw Og0KKwkJKmJ3ID0gMzsNCisJCWJyZWFrOw0KKwlkZWZhdWx0Og0KKwkJKmJ3ID0gMDsNCisJCWJy ZWFrOw0KKwl9DQorDQorCWlmIChtb2RlID09IE1UX1BIWV9UWVBFX0hUIHx8IG1vZGUgPT0gTVRf UEhZX1RZUEVfSFRfR0YpDQorCQluc3MgPSAxICsgKHJhdGVfaWR4ID4+IDMpOw0KKw0KKwlyYXRl dmFsID0gRklFTERfUFJFUChNVF9UWF9SQVRFX0lEWCwgcmF0ZV9pZHgpIHwNCisJCSAgRklFTERf UFJFUChNVF9UWF9SQVRFX01PREUsIG1vZGUpIHwNCisJCSAgRklFTERfUFJFUChNVF9UWF9SQVRF X05TUywgbnNzIC0gMSk7DQorDQorCWlmIChzdGJjICYmIG5zcyA9PSAxKSB7DQorCQluc3MrKzsN CisJCXJhdGV2YWwgfD0gTVRfVFhfUkFURV9TVEJDOw0KKwl9DQorDQorCXJldHVybiByYXRldmFs Ow0KK30NCisNCitzdGF0aWMgdm9pZA0KK210NzkxNV9tYWNfd3JpdGVfdHh3aV90bShzdHJ1Y3Qg bXQ3OTE1X2RldiAqZGV2LCBzdHJ1Y3QgbXQ3Nl9waHkgKm1waHksDQorCQkJIF9fbGUzMiAqdHh3 aSwgc3RydWN0IHNrX2J1ZmYgKnNrYikNCit7DQorI2lmZGVmIENPTkZJR19OTDgwMjExX1RFU1RN T0RFDQorCXN0cnVjdCBtdDc2X3Rlc3Rtb2RlX2RhdGEgKnRkID0gJmRldi0+bXQ3Ni50ZXN0Ow0K Kwl1OCBidywgbW9kZTsNCisJdTE2IHJhdGV2YWw7DQorCXUzMiB2YWw7DQorDQorCWlmIChza2Ig IT0gZGV2LT5tdDc2LnRlc3QudHhfc2tiKQ0KKwkJcmV0dXJuOw0KKw0KKwlzd2l0Y2ggKHRkLT50 eF9yYXRlX21vZGUpIHsNCisJY2FzZSBNVDc2X1RNX1RYX01PREVfQ0NLOg0KKwkJbW9kZSA9IE1U X1BIWV9UWVBFX0NDSzsNCisJCWJyZWFrOw0KKwljYXNlIE1UNzZfVE1fVFhfTU9ERV9IVDoNCisJ CW1vZGUgPSBNVF9QSFlfVFlQRV9IVDsNCisJCWJyZWFrOw0KKwljYXNlIE1UNzZfVE1fVFhfTU9E RV9WSFQ6DQorCQltb2RlID0gTVRfUEhZX1RZUEVfVkhUOw0KKwkJYnJlYWs7DQorCWNhc2UgTVQ3 Nl9UTV9UWF9NT0RFX0hFX1NVOg0KKwkJbW9kZSA9IE1UX1BIWV9UWVBFX0hFX1NVOw0KKwkJYnJl YWs7DQorCWNhc2UgTVQ3Nl9UTV9UWF9NT0RFX0hFX0VYVF9TVToNCisJCW1vZGUgPSBNVF9QSFlf VFlQRV9IRV9FWFRfU1U7DQorCQlicmVhazsNCisJY2FzZSBNVDc2X1RNX1RYX01PREVfSEVfVEI6 DQorCQltb2RlID0gTVRfUEhZX1RZUEVfSEVfVEI7DQorCQlicmVhazsNCisJY2FzZSBNVDc2X1RN X1RYX01PREVfSEVfTVU6DQorCQltb2RlID0gTVRfUEhZX1RZUEVfSEVfTVU7DQorCQlicmVhazsN CisJY2FzZSBNVDc2X1RNX1RYX01PREVfT0ZETToNCisJZGVmYXVsdDoNCisJCW1vZGUgPSBNVF9Q SFlfVFlQRV9PRkRNOw0KKwkJYnJlYWs7DQorCX0NCisNCisJcmF0ZXZhbCA9IG10NzkxNV9tYWNf dHhfcmF0ZV92YWwobXBoeSwgbW9kZSwgdGQtPnR4X3JhdGVfaWR4LA0KKwkJCQkJIHRkLT50eF9y YXRlX25zcywgdGQtPnR4X3JhdGVfc3RiYywgJmJ3KTsNCisNCisJdHh3aVsyXSB8PSBjcHVfdG9f bGUzMihNVF9UWEQyX0ZJWF9SQVRFKTsNCisJaWYgKHRkLT50eF9yYXRlX21vZGUgPCBNVDc2X1RN X1RYX01PREVfSFQpDQorCQl0eHdpWzNdIHw9IGNwdV90b19sZTMyKE1UX1RYRDNfQkFfRElTQUJM RSk7DQorDQorCXZhbCA9IE1UX1RYRDZfRklYRURfQlcgfA0KKwkgICAgICBGSUVMRF9QUkVQKE1U X1RYRDZfQlcsIGJ3KSB8DQorCSAgICAgIEZJRUxEX1BSRVAoTVRfVFhENl9UWF9SQVRFLCByYXRl dmFsKSB8DQorCSAgICAgIEZJRUxEX1BSRVAoTVRfVFhENl9TR0ksIHRkLT50eF9yYXRlX3NnaSk7 DQorDQorCS8qIGZvciBIRV9TVS9IRV9FWFRfU1UgUFBEVQ0KKwkgKiAtIDF4LCAyeCwgNHggTFRG ICsgMC44dXMgR0kNCisJICogLSAyeCBMVEYgKyAxLjZ1cyBHSSwgNHggTFRGICsgMy4ydXMgR0kN CisJICogZm9yIEhFX01VIFBQRFUNCisJICogLSAyeCwgNHggTFRGICsgMC44dXMgR0kNCisJICog LSAyeCBMVEYgKyAxLjZ1cyBHSSwgNHggTFRGICsgMy4ydXMgR0kNCisJICogZm9yIEhFX1RCIFBQ RFUNCisJICogLSAxeCwgMnggTFRGICsgMS42dXMgR0kNCisJICogLSA0eCBMVEYgKyAzLjJ1cyBH SQ0KKwkgKi8NCisJaWYgKG1vZGUgPj0gTVRfUEhZX1RZUEVfSEVfU1UpDQorCQl2YWwgfD0gRklF TERfUFJFUChNVF9UWEQ2X0hFTFRGLCB0ZC0+dHhfbHRmKTsNCisNCisJaWYgKHRkLT50eF9yYXRl X2xkcGMpDQorCQl2YWwgfD0gTVRfVFhENl9MRFBDOw0KKw0KKwl0eHdpWzZdIHw9IGNwdV90b19s ZTMyKHZhbCk7DQorCXR4d2lbN10gfD0gY3B1X3RvX2xlMzIoRklFTERfUFJFUChNVF9UWEQ3X1NQ RV9JRFgsDQorCQkJCQkgIGRldi0+dGVzdC5zcGVfaWR4KSk7DQorI2VuZGlmDQorfQ0KKw0KIHN0 YXRpYyB2b2lkDQogbXQ3OTE1X21hY193cml0ZV90eHdpXzgwMjMoc3RydWN0IG10NzkxNV9kZXYg KmRldiwgX19sZTMyICp0eHdpLA0KIAkJCSAgIHN0cnVjdCBza19idWZmICpza2IsIHN0cnVjdCBt dDc2X3djaWQgKndjaWQpDQpAQCAtNzYxLDYgKzg3Myw5IEBAIHZvaWQgbXQ3OTE1X21hY193cml0 ZV90eHdpKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIF9fbGUzMiAqdHh3aSwNCiAJCXR4d2lbNl0g fD0gY3B1X3RvX2xlMzIodmFsKTsNCiAJCXR4d2lbM10gfD0gY3B1X3RvX2xlMzIoTVRfVFhEM19C QV9ESVNBQkxFKTsNCiAJfQ0KKw0KKwlpZiAobXQ3Nl90ZXN0bW9kZV9lbmFibGVkKCZkZXYtPm10 NzYpKQ0KKwkJbXQ3OTE1X21hY193cml0ZV90eHdpX3RtKGRldiwgbXBoeSwgdHh3aSwgc2tiKTsN CiB9DQogDQogaW50IG10NzkxNV90eF9wcmVwYXJlX3NrYihzdHJ1Y3QgbXQ3Nl9kZXYgKm1kZXYs IHZvaWQgKnR4d2lfcHRyLA0KQEAgLTg4MSw2ICs5OTYsMTggQEAgbXQ3OTE1X3R4X2NvbXBsZXRl X3N0YXR1cyhzdHJ1Y3QgbXQ3Nl9kZXYgKm1kZXYsIHN0cnVjdCBza19idWZmICpza2IsDQogDQog CWh3ID0gbXQ3Nl90eF9zdGF0dXNfZ2V0X2h3KG1kZXYsIHNrYik7DQogDQorI2lmZGVmIENPTkZJ R19OTDgwMjExX1RFU1RNT0RFDQorCWlmIChza2IgPT0gbWRldi0+dGVzdC50eF9za2IpIHsNCisJ CXN0cnVjdCBtdDc5MTVfcGh5ICpwaHkgPSBtdDc5MTVfaHdfcGh5KGh3KTsNCisJCXN0cnVjdCBp ZWVlODAyMTFfdmlmICp2aWYgPSBwaHktPm1vbml0b3JfdmlmOw0KKwkJc3RydWN0IG10NzkxNV92 aWYgKm12aWYgPSAoc3RydWN0IG10NzkxNV92aWYgKil2aWYtPmRydl9wcml2Ow0KKw0KKwkJbXQ3 Nl90eF9jb21wbGV0ZV9za2IobWRldiwgbXZpZi0+c3RhLndjaWQuaWR4LCBza2IpOw0KKw0KKwkJ cmV0dXJuOw0KKwl9DQorI2VuZGlmDQorDQogCWlmIChpbmZvLT5mbGFncyAmIElFRUU4MDIxMV9U WF9DVExfQU1QRFUpDQogCQlpbmZvLT5mbGFncyB8PSBJRUVFODAyMTFfVFhfU1RBVF9BTVBEVTsN CiANCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210Nzkx NS9tYWluLmMgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9tYWlu LmMNCmluZGV4IDEyNjJmYjMuLjllYmU1YWYgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL25ldC93aXJl bGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9tYWluLmMNCisrKyBiL2RyaXZlcnMvbmV0L3dpcmVs ZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L21haW4uYw0KQEAgLTQ0LDEzICs0NCwxNCBAQCBzdGF0 aWMgaW50IG10NzkxNV9zdGFydChzdHJ1Y3QgaWVlZTgwMjExX2h3ICpodykNCiAJCW10NzkxNV9t YWNfZW5hYmxlX25mKGRldiwgMSk7DQogCX0NCiANCi0JbXQ3OTE1X21jdV9zZXRfc2t1X2VuKHBo eSwgdHJ1ZSk7DQorCW10NzkxNV9tY3Vfc2V0X3NrdV9lbihwaHksICFtdDc2X3Rlc3Rtb2RlX2Vu YWJsZWQoJmRldi0+bXQ3NikpOw0KIAltdDc5MTVfbWN1X3NldF9jaGFuX2luZm8ocGh5LCBNQ1Vf RVhUX0NNRF9TRVRfUlhfUEFUSCk7DQogDQogCXNldF9iaXQoTVQ3Nl9TVEFURV9SVU5OSU5HLCAm cGh5LT5tdDc2LT5zdGF0ZSk7DQogDQotCWllZWU4MDIxMV9xdWV1ZV9kZWxheWVkX3dvcmsoaHcs ICZwaHktPm1hY193b3JrLA0KLQkJCQkgICAgIE1UNzkxNV9XQVRDSERPR19USU1FKTsNCisJaWYg KCFtdDc2X3Rlc3Rtb2RlX2VuYWJsZWQoJmRldi0+bXQ3NikpDQorCQlpZWVlODAyMTFfcXVldWVf ZGVsYXllZF93b3JrKGh3LCAmcGh5LT5tYWNfd29yaywNCisJCQkJCSAgICAgTVQ3OTE1X1dBVENI RE9HX1RJTUUpOw0KIA0KIAlpZiAoIXJ1bm5pbmcpDQogCQltdDc5MTVfbWFjX3Jlc2V0X2NvdW50 ZXJzKHBoeSk7DQpAQCAtNjksNiArNzAsOCBAQCBzdGF0aWMgdm9pZCBtdDc5MTVfc3RvcChzdHJ1 Y3QgaWVlZTgwMjExX2h3ICpodykNCiANCiAJbXV0ZXhfbG9jaygmZGV2LT5tdDc2Lm11dGV4KTsN CiANCisJbXQ3Nl90ZXN0bW9kZV9yZXNldCgmZGV2LT5tdDc2LCB0cnVlKTsNCisNCiAJY2xlYXJf Yml0KE1UNzZfU1RBVEVfUlVOTklORywgJnBoeS0+bXQ3Ni0+c3RhdGUpOw0KIA0KIAlpZiAocGh5 ICE9ICZkZXYtPnBoeSkgew0KQEAgLTE1MCw2ICsxNTMsMTIgQEAgc3RhdGljIGludCBtdDc5MTVf YWRkX2ludGVyZmFjZShzdHJ1Y3QgaWVlZTgwMjExX2h3ICpodywNCiANCiAJbXV0ZXhfbG9jaygm ZGV2LT5tdDc2Lm11dGV4KTsNCiANCisJbXQ3Nl90ZXN0bW9kZV9yZXNldCgmZGV2LT5tdDc2LCB0 cnVlKTsNCisNCisJaWYgKHZpZi0+dHlwZSA9PSBOTDgwMjExX0lGVFlQRV9NT05JVE9SICYmDQor CSAgICBpc196ZXJvX2V0aGVyX2FkZHIodmlmLT5hZGRyKSkNCisJCXBoeS0+bW9uaXRvcl92aWYg PSB2aWY7DQorDQogCW12aWYtPmlkeCA9IGZmcyh+cGh5LT5tdDc2LT52aWZfbWFzaykgLSAxOw0K IAlpZiAobXZpZi0+aWR4ID49IE1UNzkxNV9NQVhfSU5URVJGQUNFUykgew0KIAkJcmV0ID0gLUVO T1NQQzsNCkBAIC0yMTgsNiArMjI3LDEzIEBAIHN0YXRpYyB2b2lkIG10NzkxNV9yZW1vdmVfaW50 ZXJmYWNlKHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LA0KIA0KIAkvKiBUT0RPOiBkaXNhYmxlIGJl YWNvbiBmb3IgdGhlIGJzcyAqLw0KIA0KKwltdXRleF9sb2NrKCZkZXYtPm10NzYubXV0ZXgpOw0K KwltdDc2X3Rlc3Rtb2RlX3Jlc2V0KCZkZXYtPm10NzYsIHRydWUpOw0KKwltdXRleF91bmxvY2so JmRldi0+bXQ3Ni5tdXRleCk7DQorDQorCWlmICh2aWYgPT0gcGh5LT5tb25pdG9yX3ZpZikNCisJ CXBoeS0+bW9uaXRvcl92aWYgPSBOVUxMOw0KKw0KIAltdDc5MTVfbWN1X2FkZF9kZXZfaW5mbyhw aHksIHZpZiwgZmFsc2UpOw0KIA0KIAlyY3VfYXNzaWduX3BvaW50ZXIoZGV2LT5tdDc2LndjaWRb aWR4XSwgTlVMTCk7DQpAQCAtMjUyLDcgKzI2OCw3IEBAIHN0YXRpYyB2b2lkIG10NzkxNV9pbml0 X2Rmc19zdGF0ZShzdHJ1Y3QgbXQ3OTE1X3BoeSAqcGh5KQ0KIAlwaHktPmRmc19zdGF0ZSA9IC0x Ow0KIH0NCiANCi1zdGF0aWMgaW50IG10NzkxNV9zZXRfY2hhbm5lbChzdHJ1Y3QgbXQ3OTE1X3Bo eSAqcGh5KQ0KK2ludCBtdDc5MTVfc2V0X2NoYW5uZWwoc3RydWN0IG10NzkxNV9waHkgKnBoeSkN CiB7DQogCXN0cnVjdCBtdDc5MTVfZGV2ICpkZXYgPSBwaHktPmRldjsNCiAJaW50IHJldDsNCkBA IC0yODEsOCArMjk3LDEwIEBAIG91dDoNCiAJbXV0ZXhfdW5sb2NrKCZkZXYtPm10NzYubXV0ZXgp Ow0KIA0KIAltdDc2X3R4cV9zY2hlZHVsZV9hbGwocGh5LT5tdDc2KTsNCi0JaWVlZTgwMjExX3F1 ZXVlX2RlbGF5ZWRfd29yayhwaHktPm10NzYtPmh3LCAmcGh5LT5tYWNfd29yaywNCi0JCQkJICAg ICBNVDc5MTVfV0FUQ0hET0dfVElNRSk7DQorDQorCWlmICghbXQ3Nl90ZXN0bW9kZV9lbmFibGVk KCZkZXYtPm10NzYpKQ0KKwkJaWVlZTgwMjExX3F1ZXVlX2RlbGF5ZWRfd29yayhwaHktPm10NzYt Pmh3LCAmcGh5LT5tYWNfd29yaywNCisJCQkJCSAgICAgTVQ3OTE1X1dBVENIRE9HX1RJTUUpOw0K IA0KIAlyZXR1cm4gcmV0Ow0KIH0NCkBAIC0zNDYsNiArMzY0LDEzIEBAIHN0YXRpYyBpbnQgbXQ3 OTE1X2NvbmZpZyhzdHJ1Y3QgaWVlZTgwMjExX2h3ICpodywgdTMyIGNoYW5nZWQpDQogCWludCBy ZXQ7DQogDQogCWlmIChjaGFuZ2VkICYgSUVFRTgwMjExX0NPTkZfQ0hBTkdFX0NIQU5ORUwpIHsN CisjaWZkZWYgQ09ORklHX05MODAyMTFfVEVTVE1PREUNCisJCWlmIChkZXYtPm10NzYudGVzdC5z dGF0ZSAhPSBNVDc2X1RNX1NUQVRFX09GRikgew0KKwkJCW11dGV4X2xvY2soJmRldi0+bXQ3Ni5t dXRleCk7DQorCQkJbXQ3Nl90ZXN0bW9kZV9yZXNldCgmZGV2LT5tdDc2LCBmYWxzZSk7DQorCQkJ bXV0ZXhfdW5sb2NrKCZkZXYtPm10NzYubXV0ZXgpOw0KKwkJfQ0KKyNlbmRpZg0KIAkJaWVlZTgw MjExX3N0b3BfcXVldWVzKGh3KTsNCiAJCXJldCA9IG10NzkxNV9zZXRfY2hhbm5lbChwaHkpOw0K IAkJaWYgKHJldCkNCkBAIC0zNzAsNiArMzk1LDcgQEAgc3RhdGljIGludCBtdDc5MTVfY29uZmln KHN0cnVjdCBpZWVlODAyMTFfaHcgKmh3LCB1MzIgY2hhbmdlZCkNCiAJCQlwaHktPnJ4ZmlsdGVy ICY9IH5NVF9XRl9SRkNSX0RST1BfT1RIRVJfVUM7DQogDQogCQltdDc2X3Jtd19maWVsZChkZXYs IE1UX0RNQV9EQ1IwLCBNVF9ETUFfRENSMF9SWERfRzVfRU4sIGVuYWJsZWQpOw0KKwkJbXQ3Nl90 ZXN0bW9kZV9yZXNldCgmZGV2LT5tdDc2LCB0cnVlKTsNCiAJCW10NzZfd3IoZGV2LCBNVF9XRl9S RkNSKGJhbmQpLCBwaHktPnJ4ZmlsdGVyKTsNCiAJfQ0KIA0KQEAgLTg4Nyw2ICs5MTMsOCBAQCBj b25zdCBzdHJ1Y3QgaWVlZTgwMjExX29wcyBtdDc5MTVfb3BzID0gew0KIAkuc2V0X2NvdmVyYWdl X2NsYXNzID0gbXQ3OTE1X3NldF9jb3ZlcmFnZV9jbGFzcywNCiAJLnN0YV9zdGF0aXN0aWNzID0g bXQ3OTE1X3N0YV9zdGF0aXN0aWNzLA0KIAkuc3RhX3NldF80YWRkciA9IG10NzkxNV9zdGFfc2V0 XzRhZGRyLA0KKwlDRkc4MDIxMV9URVNUTU9ERV9DTUQobXQ3Nl90ZXN0bW9kZV9jbWQpDQorCUNG RzgwMjExX1RFU1RNT0RFX0RVTVAobXQ3Nl90ZXN0bW9kZV9kdW1wKQ0KICNpZmRlZiBDT05GSUdf TUFDODAyMTFfREVCVUdGUw0KIAkuc3RhX2FkZF9kZWJ1Z2ZzID0gbXQ3OTE1X3N0YV9hZGRfZGVi dWdmcywNCiAjZW5kaWYNCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRl ay9tdDc2L210NzkxNS9tY3UuYyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYv bXQ3OTE1L21jdS5jDQppbmRleCA1Y2NkZTU0Li4zNzJmNDViIDEwMDY0NA0KLS0tIGEvZHJpdmVy cy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbWN1LmMNCisrKyBiL2RyaXZlcnMv bmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L21jdS5jDQpAQCAtMzE4Niw2ICszMTg2 LDE1IEBAIGludCBtdDc5MTVfbWN1X3NldF9jaGFuX2luZm8oc3RydWN0IG10NzkxNV9waHkgKnBo eSwgaW50IGNtZCkNCiAJCS5jaGFubmVsX2JhbmQgPSBjaGFuZGVmLT5jaGFuLT5iYW5kLA0KIAl9 Ow0KIA0KKyNpZmRlZiBDT05GSUdfTkw4MDIxMV9URVNUTU9ERQ0KKwlpZiAoZGV2LT5tdDc2LnRl c3QudHhfYW50ZW5uYV9tYXNrICYmDQorCSAgICAoZGV2LT5tdDc2LnRlc3Quc3RhdGUgPT0gTVQ3 Nl9UTV9TVEFURV9UWF9GUkFNRVMgfHwNCisJICAgICBkZXYtPm10NzYudGVzdC5zdGF0ZSA9PSBN VDc2X1RNX1NUQVRFX1JYX0ZSQU1FUykpIHsNCisJCXJlcS50eF9zdHJlYW1zX251bSA9IGZscyhk ZXYtPm10NzYudGVzdC50eF9hbnRlbm5hX21hc2spOw0KKwkJcmVxLnJ4X3N0cmVhbXMgPSBkZXYt Pm10NzYudGVzdC50eF9hbnRlbm5hX21hc2s7DQorCX0NCisjZW5kaWYNCisNCiAJaWYgKGRldi0+ bXQ3Ni5ody0+Y29uZi5mbGFncyAmIElFRUU4MDIxMV9DT05GX09GRkNIQU5ORUwpDQogCQlyZXEu c3dpdGNoX3JlYXNvbiA9IENIX1NXSVRDSF9TQ0FOX0JZUEFTU19EUEQ7DQogCWVsc2UgaWYgKChj aGFuZGVmLT5jaGFuLT5mbGFncyAmIElFRUU4MDIxMV9DSEFOX1JBREFSKSAmJg0KQEAgLTMzMzAs NiArMzMzOSwyOCBAQCBpbnQgbXQ3OTE1X21jdV9zZXRfdHhwb3dlcl9za3Uoc3RydWN0IG10Nzkx NV9waHkgKnBoeSkNCiAJCQkJIHNpemVvZihyZXEpLCB0cnVlKTsNCiB9DQogDQoraW50IG10Nzkx NV9tY3Vfc2V0X3Rlc3RfcGFyYW0oc3RydWN0IG10NzkxNV9kZXYgKmRldiwgdTggcGFyYW0sIGJv b2wgdGVzdF9tb2RlLA0KKwkJCSAgICAgIHU4IGVuKQ0KK3sNCisJc3RydWN0IHsNCisJCXU4IHRl c3RfbW9kZV9lbjsNCisJCXU4IHBhcmFtX2lkeDsNCisJCXU4IF9yc3ZbMl07DQorDQorCQl1OCBl bmFibGU7DQorCQl1OCBfcnN2MlszXTsNCisNCisJCXU4IHBhZFs4XTsNCisJfSBfX3BhY2tlZCBy ZXEgPSB7DQorCQkudGVzdF9tb2RlX2VuID0gdGVzdF9tb2RlLA0KKwkJLnBhcmFtX2lkeCA9IHBh cmFtLA0KKwkJLmVuYWJsZSA9IGVuLA0KKwl9Ow0KKw0KKwlyZXR1cm4gbXQ3Nl9tY3Vfc2VuZF9t c2coJmRldi0+bXQ3NiwgTUNVX0VYVF9DTURfQVRFX0NUUkwsICZyZXEsDQorCQkJCSBzaXplb2Yo cmVxKSwgZmFsc2UpOw0KK30NCisNCiBpbnQgbXQ3OTE1X21jdV9zZXRfc2t1X2VuKHN0cnVjdCBt dDc5MTVfcGh5ICpwaHksIGJvb2wgZW5hYmxlKQ0KIHsNCiAJc3RydWN0IG10NzkxNV9kZXYgKmRl diA9IHBoeS0+ZGV2Ow0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVr L210NzYvbXQ3OTE1L21jdS5oIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9t dDc5MTUvbWN1LmgNCmluZGV4IDVmMjNmMjcuLjBhN2U5ZDIgMTAwNjQ0DQotLS0gYS9kcml2ZXJz L25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS9tY3UuaA0KKysrIGIvZHJpdmVycy9u ZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbWN1LmgNCkBAIC00Niw2ICs0NiwxMCBA QCBlbnVtIHsNCiAJTUNVX0VYVF9FVkVOVF9SQVRFX1JFUE9SVCA9IDB4ODcsDQogfTsNCiANCitl bnVtIHsNCisJTUNVX0FURV9TRVRfVFJYID0gMHgxLA0KK307DQorDQogc3RydWN0IG10NzkxNV9t Y3VfcnhkIHsNCiAJX19sZTMyIHJ4ZFs2XTsNCiANCkBAIC0yMTYsNiArMjIwLDcgQEAgZW51bSB7 DQogCU1DVV9FWFRfQ01EX1dUQkxfVVBEQVRFID0gMHgzMiwNCiAJTUNVX0VYVF9DTURfU0VUX0RS Ul9DVFJMID0gMHgzNiwNCiAJTUNVX0VYVF9DTURfU0VUX1JERF9DVFJMID0gMHgzYSwNCisJTUNV X0VYVF9DTURfQVRFX0NUUkwgPSAweDNkLA0KIAlNQ1VfRVhUX0NNRF9QUk9URUNUX0NUUkwgPSAw eDNlLA0KIAlNQ1VfRVhUX0NNRF9NQUNfSU5JVF9DVFJMID0gMHg0NiwNCiAJTUNVX0VYVF9DTURf UlhfSERSX1RSQU5TID0gMHg0NywNCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9t ZWRpYXRlay9tdDc2L210NzkxNS9tdDc5MTUuaCBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlh dGVrL210NzYvbXQ3OTE1L210NzkxNS5oDQppbmRleCA0MjkyMTUzLi42NzM1OTE1IDEwMDY0NA0K LS0tIGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvbXQ3OTE1LmgN CisrKyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L210NzkxNS5o DQpAQCAtMTA4LDYgKzEwOCw4IEBAIHN0cnVjdCBtdDc5MTVfcGh5IHsNCiANCiAJc3RydWN0IGll ZWU4MDIxMV9zYmFuZF9pZnR5cGVfZGF0YSBpZnR5cGVbMl1bTlVNX05MODAyMTFfSUZUWVBFU107 DQogDQorCXN0cnVjdCBpZWVlODAyMTFfdmlmICptb25pdG9yX3ZpZjsNCisNCiAJdTMyIHJ4Zmls dGVyOw0KIAl1NjQgb21hY19tYXNrOw0KIA0KQEAgLTE1OCw2ICsxNjAsMTQgQEAgc3RydWN0IG10 NzkxNV9kZXYgew0KIAlzdHJ1Y3QgaWRyIHRva2VuOw0KIA0KIAlib29sIGZ3X2RlYnVnOw0KKw0K KyNpZmRlZiBDT05GSUdfTkw4MDIxMV9URVNUTU9ERQ0KKwlzdHJ1Y3Qgew0KKwkJdTMyICpyZWdf YmFja3VwOw0KKw0KKwkJdTggc3BlX2lkeDsNCisJfSB0ZXN0Ow0KKyNlbmRpZg0KIH07DQogDQog ZW51bSB7DQpAQCAtMjQ3LDYgKzI1Nyw3IEBAIHN0YXRpYyBpbmxpbmUgdTggbXQ3OTE1X2xtYWNf bWFwcGluZyhzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2LCB1OCBhYykNCiANCiBleHRlcm4gY29uc3Qg c3RydWN0IGllZWU4MDIxMV9vcHMgbXQ3OTE1X29wczsNCiBleHRlcm4gc3RydWN0IHBjaV9kcml2 ZXIgbXQ3OTE1X3BjaV9kcml2ZXI7DQorZXh0ZXJuIGNvbnN0IHN0cnVjdCBtdDc2X3Rlc3Rtb2Rl X29wcyBtdDc5MTVfdGVzdG1vZGVfb3BzOw0KIA0KIHUzMiBtdDc5MTVfcmVnX21hcChzdHJ1Y3Qg bXQ3OTE1X2RldiAqZGV2LCB1MzIgYWRkcik7DQogDQpAQCAtMjkyLDYgKzMwMyw3IEBAIGludCBt dDc5MTVfbWN1X2FkZF9yYXRlX2N0cmwoc3RydWN0IG10NzkxNV9kZXYgKmRldiwgc3RydWN0IGll ZWU4MDIxMV92aWYgKnZpZiwNCiAJCQkgICAgIHN0cnVjdCBpZWVlODAyMTFfc3RhICpzdGEpOw0K IGludCBtdDc5MTVfbWN1X2FkZF9zbXBzKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHN0cnVjdCBp ZWVlODAyMTFfdmlmICp2aWYsDQogCQkJc3RydWN0IGllZWU4MDIxMV9zdGEgKnN0YSk7DQoraW50 IG10NzkxNV9zZXRfY2hhbm5lbChzdHJ1Y3QgbXQ3OTE1X3BoeSAqcGh5KTsNCiBpbnQgbXQ3OTE1 X21jdV9zZXRfY2hhbl9pbmZvKHN0cnVjdCBtdDc5MTVfcGh5ICpwaHksIGludCBjbWQpOw0KIGlu dCBtdDc5MTVfbWN1X3NldF90eChzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2LCBzdHJ1Y3QgaWVlZTgw MjExX3ZpZiAqdmlmKTsNCiBpbnQgbXQ3OTE1X21jdV9zZXRfZml4ZWRfcmF0ZShzdHJ1Y3QgbXQ3 OTE1X2RldiAqZGV2LA0KQEAgLTMwMCw2ICszMTIsOCBAQCBpbnQgbXQ3OTE1X21jdV9zZXRfZWVw cm9tKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYpOw0KIGludCBtdDc5MTVfbWN1X2dldF9lZXByb20o c3RydWN0IG10NzkxNV9kZXYgKmRldiwgdTMyIG9mZnNldCk7DQogaW50IG10NzkxNV9tY3Vfc2V0 X21hYyhzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2LCBpbnQgYmFuZCwgYm9vbCBlbmFibGUsDQogCQkg ICAgICAgYm9vbCBoZHJfdHJhbnMpOw0KK2ludCBtdDc5MTVfbWN1X3NldF90ZXN0X3BhcmFtKHN0 cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHU4IHBhcmFtLCBib29sIHRlc3RfbW9kZSwNCisJCQkgICAg ICB1OCBlbik7DQogaW50IG10NzkxNV9tY3Vfc2V0X3NjcyhzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2 LCB1OCBiYW5kLCBib29sIGVuYWJsZSk7DQogaW50IG10NzkxNV9tY3Vfc2V0X3NlcihzdHJ1Y3Qg bXQ3OTE1X2RldiAqZGV2LCB1OCBhY3Rpb24sIHU4IHNldCwgdTggYmFuZCk7DQogaW50IG10Nzkx NV9tY3Vfc2V0X3J0c190aHJlc2goc3RydWN0IG10NzkxNV9waHkgKnBoeSwgdTMyIHZhbCk7DQpk aWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvcmVn cy5oIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvcmVncy5oDQpp bmRleCBlNDI1MmM4Li41MDNjOWM4IDEwMDY0NA0KLS0tIGEvZHJpdmVycy9uZXQvd2lyZWxlc3Mv bWVkaWF0ZWsvbXQ3Ni9tdDc5MTUvcmVncy5oDQorKysgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9t ZWRpYXRlay9tdDc2L210NzkxNS9yZWdzLmgNCkBAIC01MSw2ICs1MSw5IEBADQogI2RlZmluZSBN VF9XRl9UTUFDX0JBU0UoX2JhbmQpCQkoKF9iYW5kKSA/IDB4YTEwMDAgOiAweDIxMDAwKQ0KICNk ZWZpbmUgTVRfV0ZfVE1BQyhfYmFuZCwgb2ZzKQkJKE1UX1dGX1RNQUNfQkFTRShfYmFuZCkgKyAo b2ZzKSkNCiANCisjZGVmaW5lIE1UX1RNQUNfVENSMChfYmFuZCkJCU1UX1dGX1RNQUMoX2JhbmQs IDApDQorI2RlZmluZSBNVF9UTUFDX1RDUjBfVEJUVF9TVE9QX0NUUkwJQklUKDI1KQ0KKw0KICNk ZWZpbmUgTVRfVE1BQ19DRFRSKF9iYW5kKQkJTVRfV0ZfVE1BQyhfYmFuZCwgMHgwOTApDQogI2Rl ZmluZSBNVF9UTUFDX09EVFIoX2JhbmQpCQlNVF9XRl9UTUFDKF9iYW5kLCAweDA5NCkNCiAjZGVm aW5lIE1UX1RJTUVPVVRfVkFMX1BMQ1AJCUdFTk1BU0soMTUsIDApDQpAQCAtNzIsNiArNzUsOSBA QA0KICNkZWZpbmUgTVRfVE1BQ19GUDBSMTgoX2JhbmQpCQlNVF9XRl9UTUFDKF9iYW5kLCAweDI3 MCkNCiAjZGVmaW5lIE1UX1RNQUNfRlBfTUFTSwkJCUdFTk1BU0soNywgMCkNCiANCisjZGVmaW5l IE1UX1RNQUNfVFJDUjAoX2JhbmQpCQlNVF9XRl9UTUFDKF9iYW5kLCAweDA5YykNCisjZGVmaW5l IE1UX1RNQUNfVEZDUjAoX2JhbmQpCQlNVF9XRl9UTUFDKF9iYW5kLCAweDFlMCkNCisNCiAvKiBE TUEgQmFuZCAwICovDQogI2RlZmluZSBNVF9XRl9ETUFfQkFTRQkJCTB4MjFlMDANCiAjZGVmaW5l IE1UX1dGX0RNQShvZnMpCQkJKE1UX1dGX0RNQV9CQVNFICsgKG9mcykpDQpAQCAtMTcxLDEwICsx NzcsMzMgQEANCiAjZGVmaW5lIE1UX1dGX0FHR19CQVNFKF9iYW5kKQkJKChfYmFuZCkgPyAweGEw ODAwIDogMHgyMDgwMCkNCiAjZGVmaW5lIE1UX1dGX0FHRyhfYmFuZCwgb2ZzKQkJKE1UX1dGX0FH R19CQVNFKF9iYW5kKSArIChvZnMpKQ0KIA0KKyNkZWZpbmUgTVRfQUdHX0FXU0NSMChfYmFuZCwg X24pCU1UX1dGX0FHRyhfYmFuZCwgMHgwNWMgKyAoX24pICogNCkNCisjZGVmaW5lIE1UX0FHR19Q Q1IwKF9iYW5kLCBfbikJCU1UX1dGX0FHRyhfYmFuZCwgMHgwNmMgKyAoX24pICogNCkNCisjZGVm aW5lIE1UX0FHR19QQ1IwX01NX1BST1QJCUJJVCgwKQ0KKyNkZWZpbmUgTVRfQUdHX1BDUjBfR0Zf UFJPVAkJQklUKDEpDQorI2RlZmluZSBNVF9BR0dfUENSMF9CVzIwX1BST1QJCUJJVCgyKQ0KKyNk ZWZpbmUgTVRfQUdHX1BDUjBfQlc0MF9QUk9UCQlCSVQoNCkNCisjZGVmaW5lIE1UX0FHR19QQ1Iw X0JXODBfUFJPVAkJQklUKDYpDQorI2RlZmluZSBNVF9BR0dfUENSMF9FUlBfUFJPVAkJR0VOTUFT SygxMiwgOCkNCisjZGVmaW5lIE1UX0FHR19QQ1IwX1ZIVF9QUk9UCQlCSVQoMTMpDQorI2RlZmlu ZSBNVF9BR0dfUENSMF9QVEFfV0lOX0RJUwkJQklUKDE1KQ0KKw0KKyNkZWZpbmUgTVRfQUdHX1BD UjFfUlRTMF9OVU1fVEhSRVMJR0VOTUFTSygzMSwgMjMpDQorI2RlZmluZSBNVF9BR0dfUENSMV9S VFMwX0xFTl9USFJFUwlHRU5NQVNLKDE5LCAwKQ0KKw0KICNkZWZpbmUgTVRfQUdHX0FDUjAoX2Jh bmQpCQlNVF9XRl9BR0coX2JhbmQsIDB4MDg0KQ0KICNkZWZpbmUgTVRfQUdHX0FDUl9DRkVORF9S QVRFCQlHRU5NQVNLKDEzLCAwKQ0KICNkZWZpbmUgTVRfQUdHX0FDUl9CQVJfUkFURQkJR0VOTUFT SygyOSwgMTYpDQogDQorI2RlZmluZSBNVF9BR0dfTVJDUihfYmFuZCkJCU1UX1dGX0FHRyhfYmFu ZCwgMHgwOTgpDQorI2RlZmluZSBNVF9BR0dfTVJDUl9CQVJfQ05UX0xJTUlUCUdFTk1BU0soMTUs IDEyKQ0KKyNkZWZpbmUgTVRfQUdHX01SQ1JfTEFTVF9SVFNfQ1RTX1JOCUJJVCg2KQ0KKyNkZWZp bmUgTVRfQUdHX01SQ1JfUlRTX0ZBSUxfTElNSVQJR0VOTUFTSygxMSwgNykNCisjZGVmaW5lIE1U X0FHR19NUkNSX1RYQ01EX1JUU19GQUlMX0xJTUlUCUdFTk1BU0soMjgsIDI0KQ0KKw0KKyNkZWZp bmUgTVRfQUdHX0FUQ1IxKF9iYW5kKQkJTVRfV0ZfQUdHKF9iYW5kLCAweDBmMCkNCisjZGVmaW5l IE1UX0FHR19BVENSMyhfYmFuZCkJCU1UX1dGX0FHRyhfYmFuZCwgMHgwZjQpDQorDQogLyogQVJC OiBiYW5kIDAoMHgyMGMwMCksIGJhbmQgMSgweGEwYzAwKSAqLw0KICNkZWZpbmUgTVRfV0ZfQVJC X0JBU0UoX2JhbmQpCQkoKF9iYW5kKSA/IDB4YTBjMDAgOiAweDIwYzAwKQ0KICNkZWZpbmUgTVRf V0ZfQVJCKF9iYW5kLCBvZnMpCQkoTVRfV0ZfQVJCX0JBU0UoX2JhbmQpICsgKG9mcykpDQpAQCAt MTgzLDYgKzIxMiw4IEBADQogI2RlZmluZSBNVF9BUkJfU0NSX1RYX0RJU0FCTEUJCUJJVCg4KQ0K ICNkZWZpbmUgTVRfQVJCX1NDUl9SWF9ESVNBQkxFCQlCSVQoOSkNCiANCisjZGVmaW5lIE1UX0FS Ql9EUk5HUjAoX2JhbmQsIF9uKQlNVF9XRl9BUkIoX2JhbmQsIDB4MTk0ICsgKF9uKSAqIDQpDQor DQogLyogUk1BQzogYmFuZCAwKDB4MjE0MDApLCBiYW5kIDEoMHhhMTQwMCkgKi8NCiAjZGVmaW5l IE1UX1dGX1JNQUNfQkFTRShfYmFuZCkJCSgoX2JhbmQpID8gMHhhMTQwMCA6IDB4MjE0MDApDQog I2RlZmluZSBNVF9XRl9STUFDKF9iYW5kLCBvZnMpCQkoTVRfV0ZfUk1BQ19CQVNFKF9iYW5kKSAr IChvZnMpKQ0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYv bXQ3OTE1L3Rlc3Rtb2RlLmMgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210 NzkxNS90ZXN0bW9kZS5jDQpuZXcgZmlsZSBtb2RlIDEwMDY0NA0KaW5kZXggMDAwMDAwMC4uNWQ5 NTc2Ng0KLS0tIC9kZXYvbnVsbA0KKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsv bXQ3Ni9tdDc5MTUvdGVzdG1vZGUuYw0KQEAgLTAsMCArMSwxODAgQEANCisvLyBTUERYLUxpY2Vu c2UtSWRlbnRpZmllcjogSVNDDQorLyogQ29weXJpZ2h0IChDKSAyMDIwIE1lZGlhVGVrIEluYy4g Ki8NCisNCisjaW5jbHVkZSAibXQ3OTE1LmgiDQorI2luY2x1ZGUgIm1hYy5oIg0KKyNpbmNsdWRl ICJtY3UuaCINCisjaW5jbHVkZSAidGVzdG1vZGUuaCINCisNCitzdHJ1Y3QgcmVnX2JhbmQgew0K Kwl1MzIgYmFuZFsyXTsNCit9Ow0KKw0KKyNkZWZpbmUgUkVHX0JBTkQoX3JlZykgXA0KKwl7IC5i YW5kWzBdID0gTVRfIyNfcmVnKDApLCAuYmFuZFsxXSA9IE1UXyMjX3JlZygxKSB9DQorI2RlZmlu ZSBSRUdfQkFORF9JRFgoX3JlZywgX2lkeCkgXA0KKwl7IC5iYW5kWzBdID0gTVRfIyNfcmVnKDAs IF9pZHgpLCAuYmFuZFsxXSA9IE1UXyMjX3JlZygxLCBfaWR4KSB9DQorDQorc3RhdGljIGNvbnN0 IHN0cnVjdCByZWdfYmFuZCByZWdfYmFja3VwX2xpc3RbXSA9IHsNCisJUkVHX0JBTkRfSURYKEFH R19QQ1IwLCAwKSwNCisJUkVHX0JBTkRfSURYKEFHR19QQ1IwLCAxKSwNCisJUkVHX0JBTkRfSURY KEFHR19BV1NDUjAsIDApLA0KKwlSRUdfQkFORF9JRFgoQUdHX0FXU0NSMCwgMSksDQorCVJFR19C QU5EX0lEWChBR0dfQVdTQ1IwLCAyKSwNCisJUkVHX0JBTkRfSURYKEFHR19BV1NDUjAsIDMpLA0K KwlSRUdfQkFORChBR0dfTVJDUiksDQorCVJFR19CQU5EKFRNQUNfVEZDUjApLA0KKwlSRUdfQkFO RChUTUFDX1RDUjApLA0KKwlSRUdfQkFORChBR0dfQVRDUjEpLA0KKwlSRUdfQkFORChBR0dfQVRD UjMpLA0KKwlSRUdfQkFORChUTUFDX1RSQ1IwKSwNCisJUkVHX0JBTkQoVE1BQ19JQ1IwKSwNCisJ UkVHX0JBTkRfSURYKEFSQl9EUk5HUjAsIDApLA0KKwlSRUdfQkFORF9JRFgoQVJCX0RSTkdSMCwg MSksDQorfTsNCisNCitzdGF0aWMgaW50DQorbXQ3OTE1X3RtX21vZGVfY3RybChzdHJ1Y3QgbXQ3 OTE1X2RldiAqZGV2LCBib29sIGVuYWJsZSkNCit7DQorCXN0cnVjdCB7DQorCQl1OCBmb3JtYXRf aWQ7DQorCQlib29sIGVuYWJsZTsNCisJCXU4IHJzdlsyXTsNCisJfSBfX3BhY2tlZCByZXEgPSB7 DQorCQkuZm9ybWF0X2lkID0gMHg2LA0KKwkJLmVuYWJsZSA9IGVuYWJsZSwNCisJfTsNCisNCisJ cmV0dXJuIG10NzZfbWN1X3NlbmRfbXNnKCZkZXYtPm10NzYsDQorCQkJCSBNQ1VfRVhUX0NNRF9U WF9QT1dFUl9GRUFUVVJFX0NUUkwsDQorCQkJCSAmcmVxLCBzaXplb2YocmVxKSwgZmFsc2UpOw0K K30NCisNCitzdGF0aWMgaW50DQorbXQ3OTE1X3RtX3NldF90cngoc3RydWN0IG10NzkxNV9kZXYg KmRldiwgc3RydWN0IG10NzkxNV9waHkgKnBoeSwNCisJCSAgaW50IHR5cGUsIGJvb2wgZW4pDQor ew0KKwlzdHJ1Y3QgbXQ3OTE1X3RtX2NtZCByZXEgPSB7DQorCQkudGVzdG1vZGVfZW4gPSAxLA0K KwkJLnBhcmFtX2lkeCA9IE1DVV9BVEVfU0VUX1RSWCwNCisJCS5wYXJhbS50cngudHlwZSA9IHR5 cGUsDQorCQkucGFyYW0udHJ4LmVuYWJsZSA9IGVuLA0KKwkJLnBhcmFtLnRyeC5iYW5kID0gcGh5 ICE9ICZkZXYtPnBoeSwNCisJfTsNCisNCisJcmV0dXJuIG10NzZfbWN1X3NlbmRfbXNnKCZkZXYt Pm10NzYsIE1DVV9FWFRfQ01EX0FURV9DVFJMLCAmcmVxLA0KKwkJCQkgc2l6ZW9mKHJlcSksIGZh bHNlKTsNCit9DQorDQorc3RhdGljIHZvaWQNCittdDc5MTVfdG1fcmVnX2JhY2t1cF9yZXN0b3Jl KHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYsIHN0cnVjdCBtdDc5MTVfcGh5ICpwaHkpDQorew0KKwlp bnQgbl9yZWdzID0gQVJSQVlfU0laRShyZWdfYmFja3VwX2xpc3QpOw0KKwlib29sIGV4dF9waHkg PSBwaHkgIT0gJmRldi0+cGh5Ow0KKwl1MzIgKmIgPSBkZXYtPnRlc3QucmVnX2JhY2t1cDsNCisJ aW50IGk7DQorDQorCWlmIChkZXYtPm10NzYudGVzdC5zdGF0ZSA9PSBNVDc2X1RNX1NUQVRFX09G Rikgew0KKwkJZm9yIChpID0gMDsgaSA8IG5fcmVnczsgaSsrKQ0KKwkJCW10NzZfd3IoZGV2LCBy ZWdfYmFja3VwX2xpc3RbaV0uYmFuZFtleHRfcGh5XSwgYltpXSk7DQorCQlyZXR1cm47DQorCX0N CisNCisJaWYgKGIpDQorCQlyZXR1cm47DQorDQorCWIgPSBkZXZtX2t6YWxsb2MoZGV2LT5tdDc2 LmRldiwgNCAqIG5fcmVncywgR0ZQX0tFUk5FTCk7DQorCWlmICghYikNCisJCXJldHVybjsNCisN CisJZGV2LT50ZXN0LnJlZ19iYWNrdXAgPSBiOw0KKwlmb3IgKGkgPSAwOyBpIDwgbl9yZWdzOyBp KyspDQorCQliW2ldID0gbXQ3Nl9ycihkZXYsIHJlZ19iYWNrdXBfbGlzdFtpXS5iYW5kW2V4dF9w aHldKTsNCisNCisJbXQ3Nl9jbGVhcihkZXYsIE1UX0FHR19QQ1IwKGV4dF9waHksIDApLCBNVF9B R0dfUENSMF9NTV9QUk9UIHwNCisJCSAgIE1UX0FHR19QQ1IwX0dGX1BST1QgfCBNVF9BR0dfUENS MF9FUlBfUFJPVCB8DQorCQkgICBNVF9BR0dfUENSMF9WSFRfUFJPVCB8IE1UX0FHR19QQ1IwX0JX MjBfUFJPVCB8DQorCQkgICBNVF9BR0dfUENSMF9CVzQwX1BST1QgfCBNVF9BR0dfUENSMF9CVzgw X1BST1QpOw0KKwltdDc2X3NldChkZXYsIE1UX0FHR19QQ1IwKGV4dF9waHksIDApLCBNVF9BR0df UENSMF9QVEFfV0lOX0RJUyk7DQorDQorCW10NzZfd3IoZGV2LCBNVF9BR0dfUENSMChleHRfcGh5 LCAxKSwgTVRfQUdHX1BDUjFfUlRTMF9OVU1fVEhSRVMgfA0KKwkJTVRfQUdHX1BDUjFfUlRTMF9M RU5fVEhSRVMpOw0KKw0KKwltdDc2X2NsZWFyKGRldiwgTVRfQUdHX01SQ1IoMCksIE1UX0FHR19N UkNSX0JBUl9DTlRfTElNSVQgfA0KKwkJICAgTVRfQUdHX01SQ1JfTEFTVF9SVFNfQ1RTX1JOIHwg TVRfQUdHX01SQ1JfUlRTX0ZBSUxfTElNSVQgfA0KKwkJICAgTVRfQUdHX01SQ1JfVFhDTURfUlRT X0ZBSUxfTElNSVQpOw0KKw0KKwltdDc2X3JtdyhkZXYsIE1UX0FHR19NUkNSKDApLCBNVF9BR0df TVJDUl9SVFNfRkFJTF9MSU1JVCB8DQorCQkgTVRfQUdHX01SQ1JfVFhDTURfUlRTX0ZBSUxfTElN SVQsDQorCQkgRklFTERfUFJFUChNVF9BR0dfTVJDUl9SVFNfRkFJTF9MSU1JVCwgMSkgfA0KKwkJ IEZJRUxEX1BSRVAoTVRfQUdHX01SQ1JfVFhDTURfUlRTX0ZBSUxfTElNSVQsIDEpKTsNCisNCisJ bXQ3Nl93cihkZXYsIE1UX1RNQUNfVEZDUjAoMCksIDApOw0KKwltdDc2X2NsZWFyKGRldiwgTVRf VE1BQ19UQ1IwKDApLCBNVF9UTUFDX1RDUjBfVEJUVF9TVE9QX0NUUkwpOw0KK30NCisNCitzdGF0 aWMgdm9pZA0KK210NzkxNV90bV9pbml0KHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYpDQorew0KKwli b29sIGVuID0gIShkZXYtPm10NzYudGVzdC5zdGF0ZSA9PSBNVDc2X1RNX1NUQVRFX09GRik7DQor DQorCWlmICghdGVzdF9iaXQoTVQ3Nl9TVEFURV9SVU5OSU5HLCAmZGV2LT5waHkubXQ3Ni0+c3Rh dGUpKQ0KKwkJcmV0dXJuOw0KKw0KKwltdDc5MTVfdG1fbW9kZV9jdHJsKGRldiwgZW4pOw0KKwlt dDc5MTVfdG1fcmVnX2JhY2t1cF9yZXN0b3JlKGRldiwgJmRldi0+cGh5KTsNCisJbXQ3OTE1X3Rt X3NldF90cngoZGV2LCAmZGV2LT5waHksIFRNX01BQ19UWFJYLCAhZW4pOw0KK30NCisNCitzdGF0 aWMgdm9pZA0KK210NzkxNV90bV9zZXRfdHhfZnJhbWVzKHN0cnVjdCBtdDc5MTVfZGV2ICpkZXYs IGJvb2wgZW4pDQorew0KKwlzdGF0aWMgY29uc3QgdTggc3BlX2lkeF9tYXBbXSA9IHswLCAwLCAx LCAwLCAzLCAyLCA0LCAwLA0KKwkJCQkJIDksIDgsIDYsIDEwLCAxNiwgMTIsIDE4LCAwfTsNCisJ c3RydWN0IHNrX2J1ZmYgKnNrYiA9IGRldi0+bXQ3Ni50ZXN0LnR4X3NrYjsNCisJc3RydWN0IGll ZWU4MDIxMV90eF9pbmZvICppbmZvOw0KKw0KKwltdDc5MTVfdG1fc2V0X3RyeChkZXYsICZkZXYt PnBoeSwgVE1fTUFDX1JYX1JYViwgZmFsc2UpOw0KKw0KKwlpZiAoZW4pIHsNCisJCXU4IHR4X2Fu dCA9IGRldi0+bXQ3Ni50ZXN0LnR4X2FudGVubmFfbWFzazsNCisNCisJCW11dGV4X3VubG9jaygm ZGV2LT5tdDc2Lm11dGV4KTsNCisJCW10NzkxNV9zZXRfY2hhbm5lbCgmZGV2LT5waHkpOw0KKwkJ bXV0ZXhfbG9jaygmZGV2LT5tdDc2Lm11dGV4KTsNCisNCisJCW10NzkxNV9tY3Vfc2V0X2NoYW5f aW5mbygmZGV2LT5waHksIE1DVV9FWFRfQ01EX1NFVF9SWF9QQVRIKTsNCisJCWRldi0+dGVzdC5z cGVfaWR4ID0gc3BlX2lkeF9tYXBbdHhfYW50XTsNCisJfQ0KKw0KKwltdDc5MTVfdG1fc2V0X3Ry eChkZXYsICZkZXYtPnBoeSwgVE1fTUFDX1RYLCBlbik7DQorDQorCWlmICghZW4gfHwgIXNrYikN CisJCXJldHVybjsNCisNCisJaW5mbyA9IElFRUU4MDIxMV9TS0JfQ0Ioc2tiKTsNCisJaW5mby0+ Y29udHJvbC52aWYgPSBkZXYtPnBoeS5tb25pdG9yX3ZpZjsNCit9DQorDQorc3RhdGljIGludA0K K210NzkxNV90bV9zZXRfc3RhdGUoc3RydWN0IG10NzZfZGV2ICptZGV2LCBlbnVtIG10NzZfdGVz dG1vZGVfc3RhdGUgc3RhdGUpDQorew0KKwlzdHJ1Y3QgbXQ3OTE1X2RldiAqZGV2ID0gY29udGFp bmVyX29mKG1kZXYsIHN0cnVjdCBtdDc5MTVfZGV2LCBtdDc2KTsNCisJc3RydWN0IG10NzZfdGVz dG1vZGVfZGF0YSAqdGQgPSAmbWRldi0+dGVzdDsNCisJZW51bSBtdDc2X3Rlc3Rtb2RlX3N0YXRl IHByZXZfc3RhdGUgPSB0ZC0+c3RhdGU7DQorDQorCW1kZXYtPnRlc3Quc3RhdGUgPSBzdGF0ZTsN CisNCisJaWYgKHByZXZfc3RhdGUgPT0gTVQ3Nl9UTV9TVEFURV9UWF9GUkFNRVMpDQorCQltdDc5 MTVfdG1fc2V0X3R4X2ZyYW1lcyhkZXYsIGZhbHNlKTsNCisJZWxzZSBpZiAoc3RhdGUgPT0gTVQ3 Nl9UTV9TVEFURV9UWF9GUkFNRVMpDQorCQltdDc5MTVfdG1fc2V0X3R4X2ZyYW1lcyhkZXYsIHRy dWUpOw0KKwllbHNlIGlmIChwcmV2X3N0YXRlID09IE1UNzZfVE1fU1RBVEVfT0ZGIHx8IHN0YXRl ID09IE1UNzZfVE1fU1RBVEVfT0ZGKQ0KKwkJbXQ3OTE1X3RtX2luaXQoZGV2KTsNCisNCisJcmV0 dXJuIDA7DQorfQ0KKw0KK2NvbnN0IHN0cnVjdCBtdDc2X3Rlc3Rtb2RlX29wcyBtdDc5MTVfdGVz dG1vZGVfb3BzID0gew0KKwkuc2V0X3N0YXRlID0gbXQ3OTE1X3RtX3NldF9zdGF0ZSwNCit9Ow0K ZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL21lZGlhdGVrL210NzYvbXQ3OTE1L3Rl c3Rtb2RlLmggYi9kcml2ZXJzL25ldC93aXJlbGVzcy9tZWRpYXRlay9tdDc2L210NzkxNS90ZXN0 bW9kZS5oDQpuZXcgZmlsZSBtb2RlIDEwMDY0NA0KaW5kZXggMDAwMDAwMC4uMDRmNGEyYw0KLS0t IC9kZXYvbnVsbA0KKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvbWVkaWF0ZWsvbXQ3Ni9tdDc5 MTUvdGVzdG1vZGUuaA0KQEAgLTAsMCArMSwzNCBAQA0KKy8vIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBJU0MNCisvKiBDb3B5cmlnaHQgKEMpIDIwMjAgTWVkaWFUZWsgSW5jLiAqLw0KKw0KKyNp Zm5kZWYgX19NVDc5MTVfVEVTVE1PREVfSA0KKyNkZWZpbmUgX19NVDc5MTVfVEVTVE1PREVfSA0K Kw0KK3N0cnVjdCBtdDc5MTVfdG1fdHJ4IHsNCisJdTggdHlwZTsNCisJdTggZW5hYmxlOw0KKwl1 OCBiYW5kOw0KKwl1OCByc3Y7DQorfTsNCisNCitzdHJ1Y3QgbXQ3OTE1X3RtX2NtZCB7DQorCXU4 IHRlc3Rtb2RlX2VuOw0KKwl1OCBwYXJhbV9pZHg7DQorCXU4IF9yc3ZbMl07DQorCXVuaW9uIHsN CisJCV9fbGUzMiBkYXRhOw0KKwkJc3RydWN0IG10NzkxNV90bV90cnggdHJ4Ow0KKwkJdTggdGVz dFs3Ml07DQorCX0gcGFyYW07DQorfSBfX3BhY2tlZDsNCisNCitlbnVtIHsNCisJVE1fTUFDX1RY ID0gMSwNCisJVE1fTUFDX1JYLA0KKwlUTV9NQUNfVFhSWCwNCisJVE1fTUFDX1RYUlhfUlhWLA0K KwlUTV9NQUNfUlhWLA0KKwlUTV9NQUNfUlhfUlhWLA0KK307DQorDQorI2VuZGlmDQotLSANCjIu MTcuMQ0K