From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.bufferbloat.net (Postfix) with ESMTPS id 571C73B29E for ; Wed, 16 Nov 2022 15:18:23 -0500 (EST) Received: by mail-wr1-x436.google.com with SMTP id y16so31834265wrt.12 for ; Wed, 16 Nov 2022 12:18:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=3rahttK3OJh9AnzviMzdX+rvRcrwIt6BPQoV93btBf0=; b=LQNjBdSGrcUe7t7z7SQn6rWl6XynQVkdjkNTdUALiKcYEXXDoCbUQL9L+wLToWJqzz 7d51MdgJpPsSdOIFiAw74ciAO0EUoqX7WyBl+vXemwFKcXZiQbh4k4TkmMPYirrwPw5r EQ3ALAHWgYcTBxRxWTQllxJrT69BgqJq80GFxPLi7GDlLfsluGtyFD4lce+ypkrgSrbQ AtBqjjZ5233oSJtXaHJosBRGTS6mY/Hse5nDQw9ZAYh08o3FuYdP08Ayh6xdCYgatoQn 4CIbQeljKxha1gd7CHbywXFSMK5R5GrMknU9oKfdCNV2OohdbZ8/Ajxres9MAhNFjByu 5ijg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3rahttK3OJh9AnzviMzdX+rvRcrwIt6BPQoV93btBf0=; b=keW5gjoEd1Z3y/uN1TjiJGSyP7NBWNckGsmKX9gfsECXOw4vCn6WpK4x+pkg28PPxt g02XW3ZePnei3mTlGmAh+zqT2FpmOTBILlOw4K3yJd5t4zaumiQdfwrIPmYMtvnGi1+Z 1d3CLjAqPLNVJS8nbIku72HUBFz2MrPMuuZxZESkuTgqMZ3rJ7gfLSSsE2OjuFm7gzTy ec38id5gSzlvIXNRoSee/tf/a2YSWe/TXJ5s/k1G6AVaLbLFFPksJbod/r8/bsRGikil Zd/NzI4zc7HxSsuQPJc3cdn2bKlFa+74Suh8zv99Uu5V4IY5F2QJdhJOApk6tn+bFg1i yvZA== X-Gm-Message-State: ANoB5pmnXoMhX2ySxZ1TV8qQ1V6pYQYIXUlZ5t9cU1uIs3JAZDooaDSY loVa2B99JQ+WLZIbqjdVuajrBXWZeqFuIz/qpqTZ/rxF X-Google-Smtp-Source: AA0mqf5hPtG+iGnr1bOQdO32/P+B34fi8BWxw6uuqz/5soEpuCaZizdRv5+zhrcgAw7WhN9coPIwhbc1UbHvLJCyy48= X-Received: by 2002:a5d:484e:0:b0:236:5974:a5c7 with SMTP id n14-20020a5d484e000000b002365974a5c7mr14345380wrs.430.1668629901728; Wed, 16 Nov 2022 12:18:21 -0800 (PST) MIME-Version: 1.0 References: <20221116080734.44013-1-nbd@nbd.name> <20221116080734.44013-5-nbd@nbd.name> In-Reply-To: <20221116080734.44013-5-nbd@nbd.name> From: Dave Taht Date: Wed, 16 Nov 2022 12:18:09 -0800 Message-ID: To: cerowrt-devel Content-Type: multipart/alternative; boundary="0000000000008ddea905ed9c2cb7" Subject: [Cerowrt-devel] Fwd: [PATCH net-next 4/6] net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues X-BeenThere: cerowrt-devel@lists.bufferbloat.net X-Mailman-Version: 2.1.20 Precedence: list List-Id: Development issues regarding the cerowrt test router project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Nov 2022 20:18:23 -0000 --0000000000008ddea905ed9c2cb7 Content-Type: text/plain; charset="UTF-8" Fq everything ---------- Forwarded message --------- From: Felix Fietkau Date: Wed, Nov 16, 2022, 12:24 AM Subject: [PATCH net-next 4/6] net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues To: , John Crispin , Sean Wang < sean.wang@mediatek.com>, Mark Lee , Lorenzo Bianconi , David S. Miller , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Matthias Brugger , Russell King Cc: , < linux-mediatek@lists.infradead.org>, When sending traffic to multiple ports with different link speeds, queued packets to one port can drown out tx to other ports. In order to better handle transmission to multiple ports, use the hardware shaper feature to implement weighted fair queueing between ports. Weight and maximum rate are automatically adjusted based on the link speed of the port. The first 3 queues are unrestricted and reserved for non-DSA direct tx on GMAC ports. The following queues are automatically assigned by the MTK DSA tag driver based on the target port number. The PPE offload code configures the queues for offloaded traffic in the same way. This feature is only supported on devices supporting QDMA. All queues still share the same DMA ring and descriptor pool. Signed-off-by: Felix Fietkau --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 281 ++++++++++++++++---- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 26 +- 2 files changed, 258 insertions(+), 49 deletions(-) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 9e5545242216..e1cc813bbb6f 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -55,6 +55,7 @@ static const struct mtk_reg_map mtk_reg_map = { }, .qdma = { .qtx_cfg = 0x1800, + .qtx_sch = 0x1804, .rx_ptr = 0x1900, .rx_cnt_cfg = 0x1904, .qcrx_ptr = 0x1908, @@ -62,6 +63,7 @@ static const struct mtk_reg_map mtk_reg_map = { .rst_idx = 0x1a08, .delay_irq = 0x1a0c, .fc_th = 0x1a10, + .tx_sch_rate = 0x1a14, .int_grp = 0x1a20, .hred = 0x1a44, .ctx_ptr = 0x1b00, @@ -114,6 +116,7 @@ static const struct mtk_reg_map mt7986_reg_map = { }, .qdma = { .qtx_cfg = 0x4400, + .qtx_sch = 0x4404, .rx_ptr = 0x4500, .rx_cnt_cfg = 0x4504, .qcrx_ptr = 0x4508, @@ -131,6 +134,7 @@ static const struct mtk_reg_map mt7986_reg_map = { .fq_tail = 0x4724, .fq_count = 0x4728, .fq_blen = 0x472c, + .tx_sch_rate = 0x4798, }, .gdm1_cnt = 0x1c00, .gdma_to_ppe = 0x3333, @@ -614,6 +618,75 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); } +static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, + int speed) +{ + const struct mtk_soc_data *soc = eth->soc; + u32 ofs, val; + + if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) + return; + + val = MTK_QTX_SCH_MIN_RATE_EN | + /* minimum: 10 Mbps */ + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | + MTK_QTX_SCH_LEAKY_BUCKET_SIZE; + if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) + val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; + + if (IS_ENABLED(CONFIG_SOC_MT7621)) { + switch (speed) { + case SPEED_10: + val |= MTK_QTX_SCH_MAX_RATE_EN | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 2) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); + break; + case SPEED_100: + val |= MTK_QTX_SCH_MAX_RATE_EN | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3); + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); + break; + case SPEED_1000: + val |= MTK_QTX_SCH_MAX_RATE_EN | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 105) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10); + break; + default: + break; + } + } else { + switch (speed) { + case SPEED_10: + val |= MTK_QTX_SCH_MAX_RATE_EN | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); + break; + case SPEED_100: + val |= MTK_QTX_SCH_MAX_RATE_EN | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5); + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); + break; + case SPEED_1000: + val |= MTK_QTX_SCH_MAX_RATE_EN | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 10) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) | + FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10); + break; + default: + break; + } + } + + ofs = MTK_QTX_OFFSET * idx; + mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); +} + static void mtk_mac_link_up(struct phylink_config *config, struct phy_device *phy, unsigned int mode, phy_interface_t interface, @@ -639,6 +712,8 @@ static void mtk_mac_link_up(struct phylink_config *config, break; } + mtk_set_queue_speed(mac->hw, mac->id, speed); + /* Configure duplex */ if (duplex == DUPLEX_FULL) mcr |= MAC_MCR_FORCE_DPX; @@ -1099,7 +1174,8 @@ static void mtk_tx_set_dma_desc_v1(struct net_device *dev, void *txd, WRITE_ONCE(desc->txd1, info->addr); - data = TX_DMA_SWC | TX_DMA_PLEN0(info->size); + data = TX_DMA_SWC | TX_DMA_PLEN0(info->size) | + FIELD_PREP(TX_DMA_PQID, info->qid); if (info->last) data |= TX_DMA_LS0; WRITE_ONCE(desc->txd3, data); @@ -1133,9 +1209,6 @@ static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd, data |= TX_DMA_LS0; WRITE_ONCE(desc->txd3, data); - if (!info->qid && mac->id) - info->qid = MTK_QDMA_GMAC2_QID; - data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); WRITE_ONCE(desc->txd4, data); @@ -1179,11 +1252,12 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, .gso = gso, .csum = skb->ip_summed == CHECKSUM_PARTIAL, .vlan = skb_vlan_tag_present(skb), - .qid = skb->mark & MTK_QDMA_TX_MASK, + .qid = skb_get_queue_mapping(skb), .vlan_tci = skb_vlan_tag_get(skb), .first = true, .last = !skb_is_nonlinear(skb), }; + struct netdev_queue *txq; struct mtk_mac *mac = netdev_priv(dev); struct mtk_eth *eth = mac->hw; const struct mtk_soc_data *soc = eth->soc; @@ -1191,8 +1265,10 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, struct mtk_tx_dma *itxd_pdma, *txd_pdma; struct mtk_tx_buf *itx_buf, *tx_buf; int i, n_desc = 1; + int queue = skb_get_queue_mapping(skb); int k = 0; + txq = netdev_get_tx_queue(dev, queue); itxd = ring->next_free; itxd_pdma = qdma_to_pdma(ring, itxd); if (itxd == ring->last_free) @@ -1241,7 +1317,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); txd_info.size = min_t(unsigned int, frag_size, soc->txrx.dma_max_len); - txd_info.qid = skb->mark & MTK_QDMA_TX_MASK; + txd_info.qid = queue; txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && !(frag_size - txd_info.size); txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, @@ -1280,7 +1356,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, txd_pdma->txd2 |= TX_DMA_LS1; } - netdev_sent_queue(dev, skb->len); + netdev_tx_sent_queue(txq, skb->len); skb_tx_timestamp(skb); ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); @@ -1292,8 +1368,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, wmb(); if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { - if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || - !netdev_xmit_more()) + if (netif_xmit_stopped(txq) || !netdev_xmit_more()) mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); } else { int next_idx; @@ -1362,7 +1437,7 @@ static void mtk_wake_queue(struct mtk_eth *eth) for (i = 0; i < MTK_MAC_COUNT; i++) { if (!eth->netdev[i]) continue; - netif_wake_queue(eth->netdev[i]); + netif_tx_wake_all_queues(eth->netdev[i]); } } @@ -1386,7 +1461,7 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_num = mtk_cal_txd_req(eth, skb); if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { - netif_stop_queue(dev); + netif_tx_stop_all_queues(dev); netif_err(eth, tx_queued, dev, "Tx Ring full when queue awake!\n"); spin_unlock(ð->page_lock); @@ -1412,7 +1487,7 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) - netif_stop_queue(dev); + netif_tx_stop_all_queues(dev); spin_unlock(ð->page_lock); @@ -1579,10 +1654,12 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf); const struct mtk_soc_data *soc = eth->soc; struct mtk_tx_ring *ring = ð->tx_ring; + struct mtk_mac *mac = netdev_priv(dev); struct mtk_tx_dma_desc_info txd_info = { .size = xdpf->len, .first = true, .last = !xdp_frame_has_frags(xdpf), + .qid = mac->id, }; int err, index = 0, n_desc = 1, nr_frags; struct mtk_tx_buf *htx_buf, *tx_buf; @@ -1632,6 +1709,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); txd_info.size = skb_frag_size(&sinfo->frags[index]); txd_info.last = index + 1 == nr_frags; + txd_info.qid = mac->id; data = skb_frag_address(&sinfo->frags[index]); index++; @@ -1992,8 +2070,46 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, return done; } +struct mtk_poll_state { + struct netdev_queue *txq; + unsigned int total; + unsigned int done; + unsigned int bytes; +}; + +static void +mtk_poll_tx_done(struct mtk_eth *eth, struct mtk_poll_state *state, u8 mac, + struct sk_buff *skb) +{ + struct netdev_queue *txq; + struct net_device *dev; + unsigned int bytes = skb->len; + + state->total++; + eth->tx_packets++; + eth->tx_bytes += bytes; + + dev = eth->netdev[mac]; + if (!dev) + return; + + txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); + if (state->txq == txq) { + state->done++; + state->bytes += bytes; + return; + } + + if (state->txq) + netdev_tx_completed_queue(state->txq, state->done, state->bytes); + + state->txq = txq; + state->done = 1; + state->bytes = bytes; +} + static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, - unsigned int *done, unsigned int *bytes) + struct mtk_poll_state *state) { const struct mtk_reg_map *reg_map = eth->soc->reg_map; struct mtk_tx_ring *ring = ð->tx_ring; @@ -2025,12 +2141,9 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, break; if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { - if (tx_buf->type == MTK_TYPE_SKB) { - struct sk_buff *skb = tx_buf->data; + if (tx_buf->type == MTK_TYPE_SKB) + mtk_poll_tx_done(eth, state, mac, tx_buf->data); - bytes[mac] += skb->len; - done[mac]++; - } budget--; } mtk_tx_unmap(eth, tx_buf, &bq, true); @@ -2049,7 +2162,7 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, } static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget, - unsigned int *done, unsigned int *bytes) + struct mtk_poll_state *state) { struct mtk_tx_ring *ring = ð->tx_ring; struct mtk_tx_buf *tx_buf; @@ -2067,12 +2180,8 @@ static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget, break; if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { - if (tx_buf->type == MTK_TYPE_SKB) { - struct sk_buff *skb = tx_buf->data; - - bytes[0] += skb->len; - done[0]++; - } + if (tx_buf->type == MTK_TYPE_SKB) + mtk_poll_tx_done(eth, state, 0, tx_buf->data); budget--; } mtk_tx_unmap(eth, tx_buf, &bq, true); @@ -2094,26 +2203,15 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget) { struct mtk_tx_ring *ring = ð->tx_ring; struct dim_sample dim_sample = {}; - unsigned int done[MTK_MAX_DEVS]; - unsigned int bytes[MTK_MAX_DEVS]; - int total = 0, i; - - memset(done, 0, sizeof(done)); - memset(bytes, 0, sizeof(bytes)); + struct mtk_poll_state state = {}; if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) - budget = mtk_poll_tx_qdma(eth, budget, done, bytes); + budget = mtk_poll_tx_qdma(eth, budget, &state); else - budget = mtk_poll_tx_pdma(eth, budget, done, bytes); + budget = mtk_poll_tx_pdma(eth, budget, &state); - for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!eth->netdev[i] || !done[i]) - continue; - netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); - total += done[i]; - eth->tx_packets += done[i]; - eth->tx_bytes += bytes[i]; - } + if (state.txq) + netdev_tx_completed_queue(state.txq, state.done, state.bytes); dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes, &dim_sample); @@ -2123,7 +2221,7 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget) (atomic_read(&ring->free_count) > ring->thresh)) mtk_wake_queue(eth); - return total; + return state.total; } static void mtk_handle_status_irq(struct mtk_eth *eth) @@ -2209,6 +2307,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) int i, sz = soc->txrx.txd_size; struct mtk_tx_dma_v2 *txd; int ring_size; + u32 ofs, val; if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) ring_size = MTK_QDMA_RING_SIZE; @@ -2276,8 +2375,25 @@ static int mtk_tx_alloc(struct mtk_eth *eth) ring->phys + ((ring_size - 1) * sz), soc->reg_map->qdma.crx_ptr); mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); - mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, - soc->reg_map->qdma.qtx_cfg); + + for (i = 0, ofs = 0; i < MTK_QDMA_NUM_QUEUES; i++) { + val = (QDMA_RES_THRES << 8) | QDMA_RES_THRES; + mtk_w32(eth, val, soc->reg_map->qdma.qtx_cfg + ofs); + + val = MTK_QTX_SCH_MIN_RATE_EN | + /* minimum: 10 Mbps */ + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | + FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | + MTK_QTX_SCH_LEAKY_BUCKET_SIZE; + if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) + val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; + mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); + ofs += MTK_QTX_OFFSET; + } + val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16); + mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate); + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) + mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4); } else { mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); @@ -2957,7 +3073,7 @@ static int mtk_start_dma(struct mtk_eth *eth) if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) val |= MTK_MUTLI_CNT | MTK_RESV_BUF | MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | - MTK_CHK_DDONE_EN; + MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; else val |= MTK_RX_BT_32DWORDS; mtk_w32(eth, val, reg_map->qdma.glo_cfg); @@ -3014,6 +3130,45 @@ static bool mtk_uses_dsa(struct net_device *dev) #endif } +static int mtk_device_event(struct notifier_block *n, unsigned long event, void *ptr) +{ + struct mtk_mac *mac = container_of(n, struct mtk_mac, device_notifier); + struct mtk_eth *eth = mac->hw; + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct ethtool_link_ksettings s; + struct net_device *ldev; + struct list_head *iter; + struct dsa_port *dp; + + if (event != NETDEV_CHANGE) + return NOTIFY_DONE; + + netdev_for_each_lower_dev(dev, ldev, iter) { + if (netdev_priv(ldev) == mac) + goto found; + } + + return NOTIFY_DONE; + +found: + if (!dsa_slave_dev_check(dev)) + return NOTIFY_DONE; + + if (__ethtool_get_link_ksettings(dev, &s)) + return NOTIFY_DONE; + + if (s.base.speed == 0 || s.base.speed == ((__u32)-1)) + return NOTIFY_DONE; + + dp = dsa_port_from_netdev(dev); + if (dp->index >= MTK_QDMA_NUM_QUEUES) + return NOTIFY_DONE; + + mtk_set_queue_speed(eth, dp->index + 3, s.base.speed); + + return NOTIFY_DONE; +} + static int mtk_open(struct net_device *dev) { struct mtk_mac *mac = netdev_priv(dev); @@ -3078,7 +3233,8 @@ static int mtk_open(struct net_device *dev) refcount_inc(ð->dma_refcnt); phylink_start(mac->phylink); - netif_start_queue(dev); + netif_tx_start_all_queues(dev); + return 0; } @@ -3607,8 +3763,12 @@ static int mtk_unreg_dev(struct mtk_eth *eth) int i; for (i = 0; i < MTK_MAC_COUNT; i++) { + struct mtk_mac *mac; if (!eth->netdev[i]) continue; + mac = netdev_priv(eth->netdev[i]); + if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) + unregister_netdevice_notifier(&mac->device_notifier); unregister_netdev(eth->netdev[i]); } @@ -3824,6 +3984,23 @@ static int mtk_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) return ret; } +static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev) +{ + struct mtk_mac *mac = netdev_priv(dev); + unsigned int queue = 0; + + if (netdev_uses_dsa(dev)) + queue = skb_get_queue_mapping(skb) + 3; + else + queue = mac->id; + + if (queue >= dev->num_tx_queues) + queue = 0; + + return queue; +} + static const struct ethtool_ops mtk_ethtool_ops = { .get_link_ksettings = mtk_get_link_ksettings, .set_link_ksettings = mtk_set_link_ksettings, @@ -3859,6 +4036,7 @@ static const struct net_device_ops mtk_netdev_ops = { .ndo_setup_tc = mtk_eth_setup_tc, .ndo_bpf = mtk_xdp, .ndo_xdp_xmit = mtk_xdp_xmit, + .ndo_select_queue = mtk_select_queue, }; static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) @@ -3868,6 +4046,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) struct phylink *phylink; struct mtk_mac *mac; int id, err; + int txqs = 1; if (!_id) { dev_err(eth->dev, "missing mac id\n"); @@ -3885,7 +4064,10 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) return -EINVAL; } - eth->netdev[id] = alloc_etherdev(sizeof(*mac)); + if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) + txqs = MTK_QDMA_NUM_QUEUES; + + eth->netdev[id] = alloc_etherdev_mqs(sizeof(*mac), txqs, 1); if (!eth->netdev[id]) { dev_err(eth->dev, "alloc_etherdev failed\n"); return -ENOMEM; @@ -3982,6 +4164,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) else eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN; + if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { + mac->device_notifier.notifier_call = mtk_device_event; + register_netdevice_notifier(&mac->device_notifier); + } + return 0; free_netdev: diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h index eaaa0c67ef2a..1581eba053ab 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -25,6 +25,7 @@ #define MTK_MAX_DSA_PORTS 7 #define MTK_DSA_PORT_MASK GENMASK(2, 0) +#define MTK_QDMA_NUM_QUEUES 16 #define MTK_QDMA_PAGE_SIZE 2048 #define MTK_MAX_RX_LENGTH 1536 #define MTK_MAX_RX_LENGTH_2K 2048 @@ -210,8 +211,26 @@ #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) /* QDMA TX Queue Configuration Registers */ +#define MTK_QTX_OFFSET 0x10 #define QDMA_RES_THRES 4 +/* QDMA Tx Queue Scheduler Configuration Registers */ +#define MTK_QTX_SCH_TX_SEL BIT(31) +#define MTK_QTX_SCH_TX_SEL_V2 GENMASK(31, 30) + +#define MTK_QTX_SCH_LEAKY_BUCKET_EN BIT(30) +#define MTK_QTX_SCH_LEAKY_BUCKET_SIZE GENMASK(29, 28) +#define MTK_QTX_SCH_MIN_RATE_EN BIT(27) +#define MTK_QTX_SCH_MIN_RATE_MAN GENMASK(26, 20) +#define MTK_QTX_SCH_MIN_RATE_EXP GENMASK(19, 16) +#define MTK_QTX_SCH_MAX_RATE_WEIGHT GENMASK(15, 12) +#define MTK_QTX_SCH_MAX_RATE_EN BIT(11) +#define MTK_QTX_SCH_MAX_RATE_MAN GENMASK(10, 4) +#define MTK_QTX_SCH_MAX_RATE_EXP GENMASK(3, 0) + +/* QDMA TX Scheduler Rate Control Register */ +#define MTK_QDMA_TX_SCH_MAX_WFQ BIT(15) + /* QDMA Global Configuration Register */ #define MTK_RX_2B_OFFSET BIT(31) #define MTK_RX_BT_32DWORDS (3 << 11) @@ -230,6 +249,7 @@ #define MTK_WCOMP_EN BIT(24) #define MTK_RESV_BUF (0x40 << 16) #define MTK_MUTLI_CNT (0x4 << 12) +#define MTK_LEAKY_BUCKET_EN BIT(11) /* QDMA Flow Control Register */ #define FC_THRES_DROP_MODE BIT(20) @@ -258,8 +278,6 @@ #define MTK_STAT_OFFSET 0x40 /* QDMA TX NUM */ -#define MTK_QDMA_TX_NUM 16 -#define MTK_QDMA_TX_MASK (MTK_QDMA_TX_NUM - 1) #define QID_BITS_V2(x) (((x) & 0x3f) << 16) #define MTK_QDMA_GMAC2_QID 8 @@ -289,6 +307,7 @@ #define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) #define TX_DMA_SWC BIT(14) +#define TX_DMA_PQID GENMASK(3, 0) /* PDMA on MT7628 */ #define TX_DMA_DONE BIT(31) @@ -947,6 +966,7 @@ struct mtk_reg_map { } pdma; struct { u32 qtx_cfg; /* tx queue configuration */ + u32 qtx_sch; /* tx queue scheduler configuration */ u32 rx_ptr; /* rx base pointer */ u32 rx_cnt_cfg; /* rx max count configuration */ u32 qcrx_ptr; /* rx cpu pointer */ @@ -964,6 +984,7 @@ struct mtk_reg_map { u32 fq_tail; /* fq tail pointer */ u32 fq_count; /* fq free page count */ u32 fq_blen; /* fq free page buffer length */ + u32 tx_sch_rate; /* tx scheduler rate control registers */ } qdma; u32 gdm1_cnt; u32 gdma_to_ppe; @@ -1157,6 +1178,7 @@ struct mtk_mac { __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; int hwlro_ip_cnt; unsigned int syscfg0; + struct notifier_block device_notifier; }; /* the struct describing the SoC. these are declared in the soc_xyz.c files */ -- 2.38.1 --0000000000008ddea905ed9c2cb7 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: base64 PGRpdiBkaXI9ImF1dG8iPkZxIGV2ZXJ5dGhpbmfCoDwvZGl2Pjxicj48ZGl2IGNsYXNzPSJnbWFp bF9xdW90ZSI+PGRpdiBkaXI9Imx0ciIgY2xhc3M9ImdtYWlsX2F0dHIiPi0tLS0tLS0tLS0gRm9y d2FyZGVkIG1lc3NhZ2UgLS0tLS0tLS0tPGJyPkZyb206IDxzdHJvbmcgY2xhc3M9ImdtYWlsX3Nl bmRlcm5hbWUiIGRpcj0iYXV0byI+RmVsaXggRmlldGthdTwvc3Ryb25nPiA8c3BhbiBkaXI9ImF1 dG8iPiZsdDs8YSBocmVmPSJtYWlsdG86bmJkQG5iZC5uYW1lIj5uYmRAbmJkLm5hbWU8L2E+Jmd0 Ozwvc3Bhbj48YnI+RGF0ZTogV2VkLCBOb3YgMTYsIDIwMjIsIDEyOjI0IEFNPGJyPlN1YmplY3Q6 IFtQQVRDSCBuZXQtbmV4dCA0LzZdIG5ldDogZXRoZXJuZXQ6IG10a19ldGhfc29jOiBpbXBsZW1l bnQgbXVsdGktcXVldWUgc3VwcG9ydCBmb3IgcGVyLXBvcnQgcXVldWVzPGJyPlRvOiAgJmx0Ozxh IGhyZWY9Im1haWx0bzpuZXRkZXZAdmdlci5rZXJuZWwub3JnIj5uZXRkZXZAdmdlci5rZXJuZWwu b3JnPC9hPiZndDssIEpvaG4gQ3Jpc3BpbiAmbHQ7PGEgaHJlZj0ibWFpbHRvOmpvaG5AcGhyb3pl bi5vcmciPmpvaG5AcGhyb3plbi5vcmc8L2E+Jmd0OywgU2VhbiBXYW5nICZsdDs8YSBocmVmPSJt YWlsdG86c2Vhbi53YW5nQG1lZGlhdGVrLmNvbSI+c2Vhbi53YW5nQG1lZGlhdGVrLmNvbTwvYT4m Z3Q7LCBNYXJrIExlZSAmbHQ7PGEgaHJlZj0ibWFpbHRvOk1hcmstTUMuTGVlQG1lZGlhdGVrLmNv bSI+TWFyay1NQy5MZWVAbWVkaWF0ZWsuY29tPC9hPiZndDssIExvcmVuem8gQmlhbmNvbmkgJmx0 OzxhIGhyZWY9Im1haWx0bzpsb3JlbnpvQGtlcm5lbC5vcmciPmxvcmVuem9Aa2VybmVsLm9yZzwv YT4mZ3Q7LCBEYXZpZCBTLiBNaWxsZXIgJmx0OzxhIGhyZWY9Im1haWx0bzpkYXZlbUBkYXZlbWxv ZnQubmV0Ij5kYXZlbUBkYXZlbWxvZnQubmV0PC9hPiZndDssIEVyaWMgRHVtYXpldCAmbHQ7PGEg aHJlZj0ibWFpbHRvOmVkdW1hemV0QGdvb2dsZS5jb20iPmVkdW1hemV0QGdvb2dsZS5jb208L2E+ Jmd0OywgSmFrdWIgS2ljaW5za2kgJmx0OzxhIGhyZWY9Im1haWx0bzprdWJhQGtlcm5lbC5vcmci Pmt1YmFAa2VybmVsLm9yZzwvYT4mZ3Q7LCBQYW9sbyBBYmVuaSAmbHQ7PGEgaHJlZj0ibWFpbHRv OnBhYmVuaUByZWRoYXQuY29tIj5wYWJlbmlAcmVkaGF0LmNvbTwvYT4mZ3Q7LCBNYXR0aGlhcyBC cnVnZ2VyICZsdDs8YSBocmVmPSJtYWlsdG86bWF0dGhpYXMuYmdnQGdtYWlsLmNvbSI+bWF0dGhp YXMuYmdnQGdtYWlsLmNvbTwvYT4mZ3Q7LCBSdXNzZWxsIEtpbmcgJmx0OzxhIGhyZWY9Im1haWx0 bzpsaW51eEBhcm1saW51eC5vcmcudWsiPmxpbnV4QGFybWxpbnV4Lm9yZy51azwvYT4mZ3Q7PGJy PkNjOiAgJmx0OzxhIGhyZWY9Im1haWx0bzpsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVh ZC5vcmciPmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZzwvYT4mZ3Q7LCAgJmx0 OzxhIGhyZWY9Im1haWx0bzpsaW51eC1tZWRpYXRla0BsaXN0cy5pbmZyYWRlYWQub3JnIj5saW51 eC1tZWRpYXRla0BsaXN0cy5pbmZyYWRlYWQub3JnPC9hPiZndDssICAmbHQ7PGEgaHJlZj0ibWFp bHRvOmxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5lbC5vcmciPmxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5l bC5vcmc8L2E+Jmd0Ozxicj48L2Rpdj48YnI+PGJyPldoZW4gc2VuZGluZyB0cmFmZmljIHRvIG11 bHRpcGxlIHBvcnRzIHdpdGggZGlmZmVyZW50IGxpbmsgc3BlZWRzLCBxdWV1ZWQ8YnI+DQpwYWNr ZXRzIHRvIG9uZSBwb3J0IGNhbiBkcm93biBvdXQgdHggdG8gb3RoZXIgcG9ydHMuPGJyPg0KSW4g b3JkZXIgdG8gYmV0dGVyIGhhbmRsZSB0cmFuc21pc3Npb24gdG8gbXVsdGlwbGUgcG9ydHMsIHVz ZSB0aGUgaGFyZHdhcmU8YnI+DQpzaGFwZXIgZmVhdHVyZSB0byBpbXBsZW1lbnQgd2VpZ2h0ZWQg ZmFpciBxdWV1ZWluZyBiZXR3ZWVuIHBvcnRzLjxicj4NCldlaWdodCBhbmQgbWF4aW11bSByYXRl IGFyZSBhdXRvbWF0aWNhbGx5IGFkanVzdGVkIGJhc2VkIG9uIHRoZSBsaW5rIHNwZWVkPGJyPg0K b2YgdGhlIHBvcnQuPGJyPg0KVGhlIGZpcnN0IDMgcXVldWVzIGFyZSB1bnJlc3RyaWN0ZWQgYW5k IHJlc2VydmVkIGZvciBub24tRFNBIGRpcmVjdCB0eCBvbjxicj4NCkdNQUMgcG9ydHMuIFRoZSBm b2xsb3dpbmcgcXVldWVzIGFyZSBhdXRvbWF0aWNhbGx5IGFzc2lnbmVkIGJ5IHRoZSBNVEsgRFNB PGJyPg0KdGFnIGRyaXZlciBiYXNlZCBvbiB0aGUgdGFyZ2V0IHBvcnQgbnVtYmVyLjxicj4NClRo ZSBQUEUgb2ZmbG9hZCBjb2RlIGNvbmZpZ3VyZXMgdGhlIHF1ZXVlcyBmb3Igb2ZmbG9hZGVkIHRy YWZmaWMgaW4gdGhlIHNhbWU8YnI+DQp3YXkuPGJyPg0KVGhpcyBmZWF0dXJlIGlzIG9ubHkgc3Vw cG9ydGVkIG9uIGRldmljZXMgc3VwcG9ydGluZyBRRE1BLiBBbGwgcXVldWVzIHN0aWxsPGJyPg0K c2hhcmUgdGhlIHNhbWUgRE1BIHJpbmcgYW5kIGRlc2NyaXB0b3IgcG9vbC48YnI+DQo8YnI+DQpT aWduZWQtb2ZmLWJ5OiBGZWxpeCBGaWV0a2F1ICZsdDs8YSBocmVmPSJtYWlsdG86bmJkQG5iZC5u YW1lIiB0YXJnZXQ9Il9ibGFuayIgcmVsPSJub3JlZmVycmVyIj5uYmRAbmJkLm5hbWU8L2E+Jmd0 Ozxicj4NCi0tLTxicj4NCsKgZHJpdmVycy9uZXQvZXRoZXJuZXQvbWVkaWF0ZWsvbXRrX2V0aF9z b2MuYyB8IDI4MSArKysrKysrKysrKysrKysrLS0tLTxicj4NCsKgZHJpdmVycy9uZXQvZXRoZXJu ZXQvbWVkaWF0ZWsvbXRrX2V0aF9zb2MuaCB8wqAgMjYgKy08YnI+DQrCoDIgZmlsZXMgY2hhbmdl ZCwgMjU4IGluc2VydGlvbnMoKyksIDQ5IGRlbGV0aW9ucygtKTxicj4NCjxicj4NCmRpZmYgLS1n aXQgYS9kcml2ZXJzL25ldC9ldGhlcm5ldC9tZWRpYXRlay9tdGtfZXRoX3NvYy5jIGIvZHJpdmVy cy9uZXQvZXRoZXJuZXQvbWVkaWF0ZWsvbXRrX2V0aF9zb2MuYzxicj4NCmluZGV4IDllNTU0NTI0 MjIxNi4uZTFjYzgxM2JiYjZmIDEwMDY0NDxicj4NCi0tLSBhL2RyaXZlcnMvbmV0L2V0aGVybmV0 L21lZGlhdGVrL210a19ldGhfc29jLmM8YnI+DQorKysgYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9t ZWRpYXRlay9tdGtfZXRoX3NvYy5jPGJyPg0KQEAgLTU1LDYgKzU1LDcgQEAgc3RhdGljIGNvbnN0 IHN0cnVjdCBtdGtfcmVnX21hcCBtdGtfcmVnX21hcCA9IHs8YnI+DQrCoCDCoCDCoCDCoCB9LDxi cj4NCsKgIMKgIMKgIMKgIC5xZG1hID0gezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5x dHhfY2ZnwqAgwqAgwqAgwqAgPSAweDE4MDAsPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg LnF0eF9zY2jCoCDCoCDCoCDCoCA9IDB4MTgwNCw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCAucnhfcHRywqAgwqAgwqAgwqAgwqA9IDB4MTkwMCw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCAucnhfY250X2NmZ8KgIMKgIMKgPSAweDE5MDQsPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgLnFjcnhfcHRywqAgwqAgwqAgwqA9IDB4MTkwOCw8YnI+DQpAQCAtNjIsNiArNjMsNyBA QCBzdGF0aWMgY29uc3Qgc3RydWN0IG10a19yZWdfbWFwIG10a19yZWdfbWFwID0gezxicj4NCsKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5yc3RfaWR4wqAgwqAgwqAgwqAgPSAweDFhMDgsPGJyPg0K wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLmRlbGF5X2lyccKgIMKgIMKgID0gMHgxYTBjLDxicj4N CsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5mY190aMKgIMKgIMKgIMKgIMKgID0gMHgxYTEwLDxi cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC50eF9zY2hfcmF0ZcKgIMKgID0gMHgxYTE0LDxi cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5pbnRfZ3JwwqAgwqAgwqAgwqAgPSAweDFhMjAs PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLmhyZWTCoCDCoCDCoCDCoCDCoCDCoD0gMHgx YTQ0LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5jdHhfcHRywqAgwqAgwqAgwqAgPSAw eDFiMDAsPGJyPg0KQEAgLTExNCw2ICsxMTYsNyBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IG10a19y ZWdfbWFwIG10Nzk4Nl9yZWdfbWFwID0gezxicj4NCsKgIMKgIMKgIMKgIH0sPGJyPg0KwqAgwqAg wqAgwqAgLnFkbWEgPSB7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLnF0eF9jZmfCoCDC oCDCoCDCoCA9IDB4NDQwMCw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAucXR4X3NjaMKg IMKgIMKgIMKgID0gMHg0NDA0LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5yeF9wdHLC oCDCoCDCoCDCoCDCoD0gMHg0NTAwLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5yeF9j bnRfY2ZnwqAgwqAgwqA9IDB4NDUwNCw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAucWNy eF9wdHLCoCDCoCDCoCDCoD0gMHg0NTA4LDxicj4NCkBAIC0xMzEsNiArMTM0LDcgQEAgc3RhdGlj IGNvbnN0IHN0cnVjdCBtdGtfcmVnX21hcCBtdDc5ODZfcmVnX21hcCA9IHs8YnI+DQrCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCAuZnFfdGFpbMKgIMKgIMKgIMKgID0gMHg0NzI0LDxicj4NCsKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIC5mcV9jb3VudMKgIMKgIMKgIMKgPSAweDQ3MjgsPGJyPg0KwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgLmZxX2JsZW7CoCDCoCDCoCDCoCA9IDB4NDcyYyw8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAudHhfc2NoX3JhdGXCoCDCoCA9IDB4NDc5OCw8YnI+DQrC oCDCoCDCoCDCoCB9LDxicj4NCsKgIMKgIMKgIMKgIC5nZG0xX2NudMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgPSAweDFjMDAsPGJyPg0KwqAgwqAgwqAgwqAgLmdkbWFfdG9fcHBlwqAgwqAgwqAgwqAg wqAgwqAgPSAweDMzMzMsPGJyPg0KQEAgLTYxNCw2ICs2MTgsNzUgQEAgc3RhdGljIHZvaWQgbXRr X21hY19saW5rX2Rvd24oc3RydWN0IHBoeWxpbmtfY29uZmlnICpjb25maWcsIHVuc2lnbmVkIGlu dCBtb2RlLDxicj4NCsKgIMKgIMKgIMKgIG10a193MzIobWFjLSZndDtodywgbWNyLCBNVEtfTUFD X01DUihtYWMtJmd0O2lkKSk7PGJyPg0KwqB9PGJyPg0KPGJyPg0KK3N0YXRpYyB2b2lkIG10a19z ZXRfcXVldWVfc3BlZWQoc3RydWN0IG10a19ldGggKmV0aCwgdW5zaWduZWQgaW50IGlkeCw8YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpbnQgc3Bl ZWQpPGJyPg0KK3s8YnI+DQorwqAgwqAgwqAgwqBjb25zdCBzdHJ1Y3QgbXRrX3NvY19kYXRhICpz b2MgPSBldGgtJmd0O3NvYzs8YnI+DQorwqAgwqAgwqAgwqB1MzIgb2ZzLCB2YWw7PGJyPg0KKzxi cj4NCivCoCDCoCDCoCDCoGlmICghTVRLX0hBU19DQVBTKHNvYy0mZ3Q7Y2FwcywgTVRLX1FETUEp KTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybjs8YnI+DQorPGJyPg0KK8KgIMKg IMKgIMKgdmFsID0gTVRLX1FUWF9TQ0hfTUlOX1JBVEVfRU4gfDxicj4NCivCoCDCoCDCoCDCoCDC oCDCoCDCoC8qIG1pbmltdW06IDEwIE1icHMgKi88YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqBG SUVMRF9QUkVQKE1US19RVFhfU0NIX01JTl9SQVRFX01BTiwgMSkgfDxicj4NCivCoCDCoCDCoCDC oCDCoCDCoCDCoEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUlOX1JBVEVfRVhQLCA0KSB8PGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgTVRLX1FUWF9TQ0hfTEVBS1lfQlVDS0VUX1NJWkU7PGJyPg0K K8KgIMKgIMKgIMKgaWYgKCFNVEtfSEFTX0NBUFMoZXRoLSZndDtzb2MtJmd0O2NhcHMsIE1US19O RVRTWVNfVjIpKTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHZhbCB8PSBNVEtfUVRYX1ND SF9MRUFLWV9CVUNLRVRfRU47PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoGlmIChJU19FTkFCTEVE KENPTkZJR19TT0NfTVQ3NjIxKSkgezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN3aXRj aCAoc3BlZWQpIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjYXNlIFNQRUVEXzEwOjxi cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHZhbCB8PSBNVEtfUVRYX1ND SF9NQVhfUkFURV9FTiB8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUFYX1JBVEVfTUFOLCAxMDMpIHw8YnI+ DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgRklFTERfUFJF UChNVEtfUVRYX1NDSF9NQVhfUkFURV9FWFAsIDIpIHw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgRklFTERfUFJFUChNVEtfUVRYX1NDSF9NQVhfUkFU RV9XRUlHSFQsIDEpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJy ZWFrOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNhc2UgU1BFRURfMTAwOjxicj4NCivC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHZhbCB8PSBNVEtfUVRYX1NDSF9NQVhf UkFURV9FTiB8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUFYX1JBVEVfTUFOLCAxMDMpIHw8YnI+DQorwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgRklFTERfUFJFUChNVEtf UVRYX1NDSF9NQVhfUkFURV9FWFAsIDMpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCBGSUVMRF9QUkVQKE1US19RVFhfU0NIX01BWF9SQVRFX1dFSUdI VCwgMSk7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7PGJy Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY2FzZSBTUEVFRF8xMDAwOjxicj4NCivCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHZhbCB8PSBNVEtfUVRYX1NDSF9NQVhfUkFURV9F TiB8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEZJ RUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUFYX1JBVEVfTUFOLCAxMDUpIHw8YnI+DQorwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgRklFTERfUFJFUChNVEtfUVRYX1ND SF9NQVhfUkFURV9FWFAsIDQpIHw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgRklFTERfUFJFUChNVEtfUVRYX1NDSF9NQVhfUkFURV9XRUlHSFQsIDEw KTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBkZWZhdWx0Ojxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoGJyZWFrOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+ DQorwqAgwqAgwqAgwqB9IGVsc2Ugezxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN3aXRj aCAoc3BlZWQpIHs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjYXNlIFNQRUVEXzEwOjxi cj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHZhbCB8PSBNVEtfUVRYX1ND SF9NQVhfUkFURV9FTiB8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUFYX1JBVEVfTUFOLCAxKSB8PGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEZJRUxEX1BSRVAo TVRLX1FUWF9TQ0hfTUFYX1JBVEVfRVhQLCA0KSB8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUFYX1JBVEVf V0VJR0hULCAxKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVh azs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjYXNlIFNQRUVEXzEwMDo8YnI+DQorwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB2YWwgfD0gTVRLX1FUWF9TQ0hfTUFYX1JB VEVfRU4gfDxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCBGSUVMRF9QUkVQKE1US19RVFhfU0NIX01BWF9SQVRFX01BTiwgMSkgfDxicj4NCivCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBGSUVMRF9QUkVQKE1US19RVFhf U0NIX01BWF9SQVRFX0VYUCwgNSk7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUFYX1JBVEVfV0VJR0hULCAx KTs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazs8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjYXNlIFNQRUVEXzEwMDA6PGJyPg0KK8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdmFsIHw9IE1US19RVFhfU0NIX01BWF9SQVRFX0VOIHw8 YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgRklFTERf UFJFUChNVEtfUVRYX1NDSF9NQVhfUkFURV9NQU4sIDEwKSB8PGJyPg0KK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUFY X1JBVEVfRVhQLCA1KSB8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUFYX1JBVEVfV0VJR0hULCAxMCk7PGJy Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KK8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgZGVmYXVsdDo8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBicmVhazs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KK8Kg IMKgIMKgIMKgfTxicj4NCis8YnI+DQorwqAgwqAgwqAgwqBvZnMgPSBNVEtfUVRYX09GRlNFVCAq IGlkeDs8YnI+DQorwqAgwqAgwqAgwqBtdGtfdzMyKGV0aCwgdmFsLCBzb2MtJmd0O3JlZ19tYXAt Jmd0O3FkbWEucXR4X3NjaCArIG9mcyk7PGJyPg0KK308YnI+DQorPGJyPg0KwqBzdGF0aWMgdm9p ZCBtdGtfbWFjX2xpbmtfdXAoc3RydWN0IHBoeWxpbmtfY29uZmlnICpjb25maWcsPGJyPg0KwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3RydWN0IHBoeV9kZXZpY2Ug KnBoeSw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB1bnNp Z25lZCBpbnQgbW9kZSwgcGh5X2ludGVyZmFjZV90IGludGVyZmFjZSw8YnI+DQpAQCAtNjM5LDYg KzcxMiw4IEBAIHN0YXRpYyB2b2lkIG10a19tYWNfbGlua191cChzdHJ1Y3QgcGh5bGlua19jb25m aWcgKmNvbmZpZyw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBicmVhazs8YnI+DQrCoCDC oCDCoCDCoCB9PGJyPg0KPGJyPg0KK8KgIMKgIMKgIMKgbXRrX3NldF9xdWV1ZV9zcGVlZChtYWMt Jmd0O2h3LCBtYWMtJmd0O2lkLCBzcGVlZCk7PGJyPg0KKzxicj4NCsKgIMKgIMKgIMKgIC8qIENv bmZpZ3VyZSBkdXBsZXggKi88YnI+DQrCoCDCoCDCoCDCoCBpZiAoZHVwbGV4ID09IERVUExFWF9G VUxMKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG1jciB8PSBNQUNfTUNSX0ZPUkNFX0RQ WDs8YnI+DQpAQCAtMTA5OSw3ICsxMTc0LDggQEAgc3RhdGljIHZvaWQgbXRrX3R4X3NldF9kbWFf ZGVzY192MShzdHJ1Y3QgbmV0X2RldmljZSAqZGV2LCB2b2lkICp0eGQsPGJyPg0KPGJyPg0KwqAg wqAgwqAgwqAgV1JJVEVfT05DRShkZXNjLSZndDt0eGQxLCBpbmZvLSZndDthZGRyKTs8YnI+DQo8 YnI+DQotwqAgwqAgwqAgwqBkYXRhID0gVFhfRE1BX1NXQyB8IFRYX0RNQV9QTEVOMChpbmZvLSZn dDtzaXplKTs8YnI+DQorwqAgwqAgwqAgwqBkYXRhID0gVFhfRE1BX1NXQyB8IFRYX0RNQV9QTEVO MChpbmZvLSZndDtzaXplKSB8PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIEZJRUxEX1BSRVAo VFhfRE1BX1BRSUQsIGluZm8tJmd0O3FpZCk7PGJyPg0KwqAgwqAgwqAgwqAgaWYgKGluZm8tJmd0 O2xhc3QpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZGF0YSB8PSBUWF9ETUFfTFMwOzxi cj4NCsKgIMKgIMKgIMKgIFdSSVRFX09OQ0UoZGVzYy0mZ3Q7dHhkMywgZGF0YSk7PGJyPg0KQEAg LTExMzMsOSArMTIwOSw2IEBAIHN0YXRpYyB2b2lkIG10a190eF9zZXRfZG1hX2Rlc2NfdjIoc3Ry dWN0IG5ldF9kZXZpY2UgKmRldiwgdm9pZCAqdHhkLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIGRhdGEgfD0gVFhfRE1BX0xTMDs8YnI+DQrCoCDCoCDCoCDCoCBXUklURV9PTkNFKGRlc2Mt Jmd0O3R4ZDMsIGRhdGEpOzxicj4NCjxicj4NCi3CoCDCoCDCoCDCoGlmICghaW5mby0mZ3Q7cWlk ICZhbXA7JmFtcDsgbWFjLSZndDtpZCk8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpbmZv LSZndDtxaWQgPSBNVEtfUURNQV9HTUFDMl9RSUQ7PGJyPg0KLTxicj4NCsKgIMKgIMKgIMKgIGRh dGEgPSAobWFjLSZndDtpZCArIDEpICZsdDsmbHQ7IFRYX0RNQV9GUE9SVF9TSElGVF9WMjsgLyog Zm9yd2FyZCBwb3J0ICovPGJyPg0KwqAgwqAgwqAgwqAgZGF0YSB8PSBUWF9ETUFfU1dDX1YyIHwg UUlEX0JJVFNfVjIoaW5mby0mZ3Q7cWlkKTs8YnI+DQrCoCDCoCDCoCDCoCBXUklURV9PTkNFKGRl c2MtJmd0O3R4ZDQsIGRhdGEpOzxicj4NCkBAIC0xMTc5LDExICsxMjUyLDEyIEBAIHN0YXRpYyBp bnQgbXRrX3R4X21hcChzdHJ1Y3Qgc2tfYnVmZiAqc2tiLCBzdHJ1Y3QgbmV0X2RldmljZSAqZGV2 LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5nc28gPSBnc28sPGJyPg0KwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgLmNzdW0gPSBza2ItJmd0O2lwX3N1bW1lZCA9PSBDSEVDS1NVTV9QQVJU SUFMLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC52bGFuID0gc2tiX3ZsYW5fdGFnX3By ZXNlbnQoc2tiKSw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAucWlkID0gc2tiLSZndDtt YXJrICZhbXA7IE1US19RRE1BX1RYX01BU0ssPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg LnFpZCA9IHNrYl9nZXRfcXVldWVfbWFwcGluZyhza2IpLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIC52bGFuX3RjaSA9IHNrYl92bGFuX3RhZ19nZXQoc2tiKSw8YnI+DQrCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCAuZmlyc3QgPSB0cnVlLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IC5sYXN0ID0gIXNrYl9pc19ub25saW5lYXIoc2tiKSw8YnI+DQrCoCDCoCDCoCDCoCB9Ozxicj4N CivCoCDCoCDCoCDCoHN0cnVjdCBuZXRkZXZfcXVldWUgKnR4cTs8YnI+DQrCoCDCoCDCoCDCoCBz dHJ1Y3QgbXRrX21hYyAqbWFjID0gbmV0ZGV2X3ByaXYoZGV2KTs8YnI+DQrCoCDCoCDCoCDCoCBz dHJ1Y3QgbXRrX2V0aCAqZXRoID0gbWFjLSZndDtodzs8YnI+DQrCoCDCoCDCoCDCoCBjb25zdCBz dHJ1Y3QgbXRrX3NvY19kYXRhICpzb2MgPSBldGgtJmd0O3NvYzs8YnI+DQpAQCAtMTE5MSw4ICsx MjY1LDEwIEBAIHN0YXRpYyBpbnQgbXRrX3R4X21hcChzdHJ1Y3Qgc2tfYnVmZiAqc2tiLCBzdHJ1 Y3QgbmV0X2RldmljZSAqZGV2LDxicj4NCsKgIMKgIMKgIMKgIHN0cnVjdCBtdGtfdHhfZG1hICpp dHhkX3BkbWEsICp0eGRfcGRtYTs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3QgbXRrX3R4X2J1ZiAq aXR4X2J1ZiwgKnR4X2J1Zjs8YnI+DQrCoCDCoCDCoCDCoCBpbnQgaSwgbl9kZXNjID0gMTs8YnI+ DQorwqAgwqAgwqAgwqBpbnQgcXVldWUgPSBza2JfZ2V0X3F1ZXVlX21hcHBpbmcoc2tiKTs8YnI+ DQrCoCDCoCDCoCDCoCBpbnQgayA9IDA7PGJyPg0KPGJyPg0KK8KgIMKgIMKgIMKgdHhxID0gbmV0 ZGV2X2dldF90eF9xdWV1ZShkZXYsIHF1ZXVlKTs8YnI+DQrCoCDCoCDCoCDCoCBpdHhkID0gcmlu Zy0mZ3Q7bmV4dF9mcmVlOzxicj4NCsKgIMKgIMKgIMKgIGl0eGRfcGRtYSA9IHFkbWFfdG9fcGRt YShyaW5nLCBpdHhkKTs8YnI+DQrCoCDCoCDCoCDCoCBpZiAoaXR4ZCA9PSByaW5nLSZndDtsYXN0 X2ZyZWUpPGJyPg0KQEAgLTEyNDEsNyArMTMxNyw3IEBAIHN0YXRpYyBpbnQgbXRrX3R4X21hcChz dHJ1Y3Qgc2tfYnVmZiAqc2tiLCBzdHJ1Y3QgbmV0X2RldmljZSAqZGV2LDxicj4NCsKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG1lbXNldCgmYW1wO3R4ZF9pbmZvLCAwLCBzaXpl b2Yoc3RydWN0IG10a190eF9kbWFfZGVzY19pbmZvKSk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgdHhkX2luZm8uc2l6ZSA9IG1pbl90KHVuc2lnbmVkIGludCwgZnJh Z19zaXplLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHNvYy0mZ3Q7dHhyeC5kbWFfbWF4X2xlbik7PGJyPg0K LcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdHhkX2luZm8ucWlkID0gc2tiLSZn dDttYXJrICZhbXA7IE1US19RRE1BX1RYX01BU0s7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgdHhkX2luZm8ucWlkID0gcXVldWU7PGJyPg0KwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgdHhkX2luZm8ubGFzdCA9IGkgPT0gc2tiX3NoaW5mbyhza2Ip LSZndDtucl9mcmFncyAtIDEgJmFtcDsmYW1wOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICEoZnJhZ19zaXplIC0gdHhkX2lu Zm8uc2l6ZSk7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdHhkX2lu Zm8uYWRkciA9IHNrYl9mcmFnX2RtYV9tYXAoZXRoLSZndDtkbWFfZGV2LCBmcmFnLDxicj4NCkBA IC0xMjgwLDcgKzEzNTYsNyBAQCBzdGF0aWMgaW50IG10a190eF9tYXAoc3RydWN0IHNrX2J1ZmYg KnNrYiwgc3RydWN0IG5ldF9kZXZpY2UgKmRldiw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCB0eGRfcGRtYS0mZ3Q7dHhkMiB8PSBUWF9ETUFfTFMxOzxicj4NCsKgIMKg IMKgIMKgIH08YnI+DQo8YnI+DQotwqAgwqAgwqAgwqBuZXRkZXZfc2VudF9xdWV1ZShkZXYsIHNr Yi0mZ3Q7bGVuKTs8YnI+DQorwqAgwqAgwqAgwqBuZXRkZXZfdHhfc2VudF9xdWV1ZSh0eHEsIHNr Yi0mZ3Q7bGVuKTs8YnI+DQrCoCDCoCDCoCDCoCBza2JfdHhfdGltZXN0YW1wKHNrYik7PGJyPg0K PGJyPg0KwqAgwqAgwqAgwqAgcmluZy0mZ3Q7bmV4dF9mcmVlID0gbXRrX3FkbWFfcGh5c190b192 aXJ0KHJpbmcsIHR4ZC0mZ3Q7dHhkMik7PGJyPg0KQEAgLTEyOTIsOCArMTM2OCw3IEBAIHN0YXRp YyBpbnQgbXRrX3R4X21hcChzdHJ1Y3Qgc2tfYnVmZiAqc2tiLCBzdHJ1Y3QgbmV0X2RldmljZSAq ZGV2LDxicj4NCsKgIMKgIMKgIMKgIHdtYigpOzxicj4NCjxicj4NCsKgIMKgIMKgIMKgIGlmIChN VEtfSEFTX0NBUFMoc29jLSZndDtjYXBzLCBNVEtfUURNQSkpIHs8YnI+DQotwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBpZiAobmV0aWZfeG1pdF9zdG9wcGVkKG5ldGRldl9nZXRfdHhfcXVldWUoZGV2 LCAwKSkgfHw8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAhbmV0ZGV2X3htaXRf bW9yZSgpKTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChuZXRpZl94bWl0X3N0b3Bw ZWQodHhxKSB8fCAhbmV0ZGV2X3htaXRfbW9yZSgpKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIG10a193MzIoZXRoLCB0eGQtJmd0O3R4ZDIsIHNvYy0mZ3Q7cmVnX21h cC0mZ3Q7cWRtYS5jdHhfcHRyKTs8YnI+DQrCoCDCoCDCoCDCoCB9IGVsc2Ugezxicj4NCsKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIGludCBuZXh0X2lkeDs8YnI+DQpAQCAtMTM2Miw3ICsxNDM3LDcg QEAgc3RhdGljIHZvaWQgbXRrX3dha2VfcXVldWUoc3RydWN0IG10a19ldGggKmV0aCk8YnI+DQrC oCDCoCDCoCDCoCBmb3IgKGkgPSAwOyBpICZsdDsgTVRLX01BQ19DT1VOVDsgaSsrKSB7PGJyPg0K wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKCFldGgtJmd0O25ldGRldltpXSk8YnI+DQrCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjb250aW51ZTs8YnI+DQotwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBuZXRpZl93YWtlX3F1ZXVlKGV0aC0mZ3Q7bmV0ZGV2W2ldKTs8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBuZXRpZl90eF93YWtlX2FsbF9xdWV1ZXMoZXRoLSZndDtu ZXRkZXZbaV0pOzxicj4NCsKgIMKgIMKgIMKgIH08YnI+DQrCoH08YnI+DQo8YnI+DQpAQCAtMTM4 Niw3ICsxNDYxLDcgQEAgc3RhdGljIG5ldGRldl90eF90IG10a19zdGFydF94bWl0KHN0cnVjdCBz a19idWZmICpza2IsIHN0cnVjdCBuZXRfZGV2aWNlICpkZXYpPGJyPg0KPGJyPg0KwqAgwqAgwqAg wqAgdHhfbnVtID0gbXRrX2NhbF90eGRfcmVxKGV0aCwgc2tiKTs8YnI+DQrCoCDCoCDCoCDCoCBp ZiAodW5saWtlbHkoYXRvbWljX3JlYWQoJmFtcDtyaW5nLSZndDtmcmVlX2NvdW50KSAmbHQ7PSB0 eF9udW0pKSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbmV0aWZfc3RvcF9xdWV1ZShk ZXYpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG5ldGlmX3R4X3N0b3BfYWxsX3F1ZXVl cyhkZXYpOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG5ldGlmX2VycihldGgsIHR4X3F1 ZXVlZCwgZGV2LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICZx dW90O1R4IFJpbmcgZnVsbCB3aGVuIHF1ZXVlIGF3YWtlIVxuJnF1b3Q7KTs8YnI+DQrCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCBzcGluX3VubG9jaygmYW1wO2V0aC0mZ3Q7cGFnZV9sb2NrKTs8YnI+ DQpAQCAtMTQxMiw3ICsxNDg3LDcgQEAgc3RhdGljIG5ldGRldl90eF90IG10a19zdGFydF94bWl0 KHN0cnVjdCBza19idWZmICpza2IsIHN0cnVjdCBuZXRfZGV2aWNlICpkZXYpPGJyPg0KwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgZ290byBkcm9wOzxicj4NCjxicj4NCsKgIMKgIMKgIMKgIGlmICh1 bmxpa2VseShhdG9taWNfcmVhZCgmYW1wO3JpbmctJmd0O2ZyZWVfY291bnQpICZsdDs9IHJpbmct Jmd0O3RocmVzaCkpPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbmV0aWZfc3RvcF9xdWV1 ZShkZXYpOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG5ldGlmX3R4X3N0b3BfYWxsX3F1 ZXVlcyhkZXYpOzxicj4NCjxicj4NCsKgIMKgIMKgIMKgIHNwaW5fdW5sb2NrKCZhbXA7ZXRoLSZn dDtwYWdlX2xvY2spOzxicj4NCjxicj4NCkBAIC0xNTc5LDEwICsxNjU0LDEyIEBAIHN0YXRpYyBp bnQgbXRrX3hkcF9zdWJtaXRfZnJhbWUoc3RydWN0IG10a19ldGggKmV0aCwgc3RydWN0IHhkcF9m cmFtZSAqeGRwZiw8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3Qgc2tiX3NoYXJlZF9pbmZvICpzaW5m byA9IHhkcF9nZXRfc2hhcmVkX2luZm9fZnJvbV9mcmFtZSh4ZHBmKTs8YnI+DQrCoCDCoCDCoCDC oCBjb25zdCBzdHJ1Y3QgbXRrX3NvY19kYXRhICpzb2MgPSBldGgtJmd0O3NvYzs8YnI+DQrCoCDC oCDCoCDCoCBzdHJ1Y3QgbXRrX3R4X3JpbmcgKnJpbmcgPSAmYW1wO2V0aC0mZ3Q7dHhfcmluZzs8 YnI+DQorwqAgwqAgwqAgwqBzdHJ1Y3QgbXRrX21hYyAqbWFjID0gbmV0ZGV2X3ByaXYoZGV2KTs8 YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3QgbXRrX3R4X2RtYV9kZXNjX2luZm8gdHhkX2luZm8gPSB7 PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLnNpemXCoCDCoD0geGRwZi0mZ3Q7bGVuLDxi cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC5maXJzdMKgID0gdHJ1ZSw8YnI+DQrCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCAubGFzdMKgIMKgPSAheGRwX2ZyYW1lX2hhc19mcmFncyh4ZHBmKSw8 YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAucWlkwqAgwqAgPSBtYWMtJmd0O2lkLDxicj4N CsKgIMKgIMKgIMKgIH07PGJyPg0KwqAgwqAgwqAgwqAgaW50IGVyciwgaW5kZXggPSAwLCBuX2Rl c2MgPSAxLCBucl9mcmFnczs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3QgbXRrX3R4X2J1ZiAqaHR4 X2J1ZiwgKnR4X2J1Zjs8YnI+DQpAQCAtMTYzMiw2ICsxNzA5LDcgQEAgc3RhdGljIGludCBtdGtf eGRwX3N1Ym1pdF9mcmFtZShzdHJ1Y3QgbXRrX2V0aCAqZXRoLCBzdHJ1Y3QgeGRwX2ZyYW1lICp4 ZHBmLDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG1lbXNldCgmYW1wO3R4ZF9pbmZvLCAw LCBzaXplb2Yoc3RydWN0IG10a190eF9kbWFfZGVzY19pbmZvKSk7PGJyPg0KwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgdHhkX2luZm8uc2l6ZSA9IHNrYl9mcmFnX3NpemUoJmFtcDtzaW5mby0mZ3Q7 ZnJhZ3NbaW5kZXhdKTs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB0eGRfaW5mby5sYXN0 ID0gaW5kZXggKyAxID09IG5yX2ZyYWdzOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHR4 ZF9pbmZvLnFpZCA9IG1hYy0mZ3Q7aWQ7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZGF0 YSA9IHNrYl9mcmFnX2FkZHJlc3MoJmFtcDtzaW5mby0mZ3Q7ZnJhZ3NbaW5kZXhdKTs8YnI+DQo8 YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpbmRleCsrOzxicj4NCkBAIC0xOTkyLDggKzIw NzAsNDYgQEAgc3RhdGljIGludCBtdGtfcG9sbF9yeChzdHJ1Y3QgbmFwaV9zdHJ1Y3QgKm5hcGks IGludCBidWRnZXQsPGJyPg0KwqAgwqAgwqAgwqAgcmV0dXJuIGRvbmU7PGJyPg0KwqB9PGJyPg0K PGJyPg0KK3N0cnVjdCBtdGtfcG9sbF9zdGF0ZSB7PGJyPg0KK8KgIMKgIHN0cnVjdCBuZXRkZXZf cXVldWUgKnR4cTs8YnI+DQorwqAgwqAgdW5zaWduZWQgaW50IHRvdGFsOzxicj4NCivCoCDCoCB1 bnNpZ25lZCBpbnQgZG9uZTs8YnI+DQorwqAgwqAgdW5zaWduZWQgaW50IGJ5dGVzOzxicj4NCit9 Ozxicj4NCis8YnI+DQorc3RhdGljIHZvaWQ8YnI+DQorbXRrX3BvbGxfdHhfZG9uZShzdHJ1Y3Qg bXRrX2V0aCAqZXRoLCBzdHJ1Y3QgbXRrX3BvbGxfc3RhdGUgKnN0YXRlLCB1OCBtYWMsPGJyPg0K K8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHN0cnVjdCBza19idWZmICpza2IpPGJyPg0KK3s8YnI+ DQorwqAgwqAgwqAgwqBzdHJ1Y3QgbmV0ZGV2X3F1ZXVlICp0eHE7PGJyPg0KK8KgIMKgIMKgIMKg c3RydWN0IG5ldF9kZXZpY2UgKmRldjs8YnI+DQorwqAgwqAgwqAgwqB1bnNpZ25lZCBpbnQgYnl0 ZXMgPSBza2ItJmd0O2xlbjs8YnI+DQorPGJyPg0KK8KgIMKgIMKgIMKgc3RhdGUtJmd0O3RvdGFs Kys7PGJyPg0KK8KgIMKgIMKgIMKgZXRoLSZndDt0eF9wYWNrZXRzKys7PGJyPg0KK8KgIMKgIMKg IMKgZXRoLSZndDt0eF9ieXRlcyArPSBieXRlczs8YnI+DQorPGJyPg0KK8KgIMKgIMKgIMKgZGV2 ID0gZXRoLSZndDtuZXRkZXZbbWFjXTs8YnI+DQorwqAgwqAgwqAgwqBpZiAoIWRldik8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm47PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoHR4 cSA9IG5ldGRldl9nZXRfdHhfcXVldWUoZGV2LCBza2JfZ2V0X3F1ZXVlX21hcHBpbmcoc2tiKSk7 PGJyPg0KK8KgIMKgIMKgIMKgaWYgKHN0YXRlLSZndDt0eHEgPT0gdHhxKSB7PGJyPg0KK8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgc3RhdGUtJmd0O2RvbmUrKzs8YnI+DQorwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBzdGF0ZS0mZ3Q7Ynl0ZXMgKz0gYnl0ZXM7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKg IMKgIMKgcmV0dXJuOzxicj4NCivCoCDCoCDCoCDCoH08YnI+DQorPGJyPg0KK8KgIMKgIMKgIMKg aWYgKHN0YXRlLSZndDt0eHEpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbmV0ZGV2X3R4 X2NvbXBsZXRlZF9xdWV1ZShzdGF0ZS0mZ3Q7dHhxLCBzdGF0ZS0mZ3Q7ZG9uZSwgc3RhdGUtJmd0 O2J5dGVzKTs8YnI+DQorPGJyPg0KK8KgIMKgIMKgIMKgc3RhdGUtJmd0O3R4cSA9IHR4cTs8YnI+ DQorwqAgwqAgwqAgwqBzdGF0ZS0mZ3Q7ZG9uZSA9IDE7PGJyPg0KK8KgIMKgIMKgIMKgc3RhdGUt Jmd0O2J5dGVzID0gYnl0ZXM7PGJyPg0KK308YnI+DQorPGJyPg0KwqBzdGF0aWMgaW50IG10a19w b2xsX3R4X3FkbWEoc3RydWN0IG10a19ldGggKmV0aCwgaW50IGJ1ZGdldCw8YnI+DQotwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB1bnNpZ25lZCBpbnQgKmRvbmUsIHVu c2lnbmVkIGludCAqYnl0ZXMpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgc3RydWN0IG10a19wb2xsX3N0YXRlICpzdGF0ZSk8YnI+DQrCoHs8YnI+DQrCoCDC oCDCoCDCoCBjb25zdCBzdHJ1Y3QgbXRrX3JlZ19tYXAgKnJlZ19tYXAgPSBldGgtJmd0O3NvYy0m Z3Q7cmVnX21hcDs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3QgbXRrX3R4X3JpbmcgKnJpbmcgPSAm YW1wO2V0aC0mZ3Q7dHhfcmluZzs8YnI+DQpAQCAtMjAyNSwxMiArMjE0MSw5IEBAIHN0YXRpYyBp bnQgbXRrX3BvbGxfdHhfcWRtYShzdHJ1Y3QgbXRrX2V0aCAqZXRoLCBpbnQgYnVkZ2V0LDxicj4N CsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFrOzxicj4NCjxicj4NCsKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmICh0eF9idWYtJmd0O2RhdGEgIT0gKHZvaWQgKilNVEtf RE1BX0RVTU1ZX0RFU0MpIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBpZiAodHhfYnVmLSZndDt0eXBlID09IE1US19UWVBFX1NLQikgezxicj4NCi3CoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN0cnVjdCBza19idWZmICpza2Ig PSB0eF9idWYtJmd0O2RhdGE7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgaWYgKHR4X2J1Zi0mZ3Q7dHlwZSA9PSBNVEtfVFlQRV9TS0IpPGJyPg0KK8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbXRrX3BvbGxfdHhfZG9uZShldGgs IHN0YXRlLCBtYWMsIHR4X2J1Zi0mZ3Q7ZGF0YSk7PGJyPg0KPGJyPg0KLcKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnl0ZXNbbWFjXSArPSBza2ItJmd0O2xl bjs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBk b25lW21hY10rKzs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJy Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYnVkZ2V0LS07PGJyPg0KwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgfTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG10a190 eF91bm1hcChldGgsIHR4X2J1ZiwgJmFtcDticSwgdHJ1ZSk7PGJyPg0KQEAgLTIwNDksNyArMjE2 Miw3IEBAIHN0YXRpYyBpbnQgbXRrX3BvbGxfdHhfcWRtYShzdHJ1Y3QgbXRrX2V0aCAqZXRoLCBp bnQgYnVkZ2V0LDxicj4NCsKgfTxicj4NCjxicj4NCsKgc3RhdGljIGludCBtdGtfcG9sbF90eF9w ZG1hKHN0cnVjdCBtdGtfZXRoICpldGgsIGludCBidWRnZXQsPGJyPg0KLcKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdW5zaWduZWQgaW50ICpkb25lLCB1bnNpZ25lZCBp bnQgKmJ5dGVzKTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oHN0cnVjdCBtdGtfcG9sbF9zdGF0ZSAqc3RhdGUpPGJyPg0KwqB7PGJyPg0KwqAgwqAgwqAgwqAg c3RydWN0IG10a190eF9yaW5nICpyaW5nID0gJmFtcDtldGgtJmd0O3R4X3Jpbmc7PGJyPg0KwqAg wqAgwqAgwqAgc3RydWN0IG10a190eF9idWYgKnR4X2J1Zjs8YnI+DQpAQCAtMjA2NywxMiArMjE4 MCw4IEBAIHN0YXRpYyBpbnQgbXRrX3BvbGxfdHhfcGRtYShzdHJ1Y3QgbXRrX2V0aCAqZXRoLCBp bnQgYnVkZ2V0LDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFr Ozxicj4NCjxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmICh0eF9idWYtJmd0O2RhdGEg IT0gKHZvaWQgKilNVEtfRE1BX0RVTU1ZX0RFU0MpIHs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqBpZiAodHhfYnVmLSZndDt0eXBlID09IE1US19UWVBFX1NLQikgezxi cj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN0cnVj dCBza19idWZmICpza2IgPSB0eF9idWYtJmd0O2RhdGE7PGJyPg0KLTxicj4NCi3CoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJ5dGVzWzBdICs9IHNrYi0mZ3Q7 bGVuOzxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oGRvbmVbMF0rKzs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJy Pg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKHR4X2J1Zi0mZ3Q7dHlw ZSA9PSBNVEtfVFlQRV9TS0IpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgbXRrX3BvbGxfdHhfZG9uZShldGgsIHN0YXRlLCAwLCB0eF9idWYtJmd0 O2RhdGEpOzxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGJ1ZGdldC0t Ozxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH08YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCBtdGtfdHhfdW5tYXAoZXRoLCB0eF9idWYsICZhbXA7YnEsIHRydWUpOzxicj4NCkBAIC0y MDk0LDI2ICsyMjAzLDE1IEBAIHN0YXRpYyBpbnQgbXRrX3BvbGxfdHgoc3RydWN0IG10a19ldGgg KmV0aCwgaW50IGJ1ZGdldCk8YnI+DQrCoHs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1Y3QgbXRrX3R4 X3JpbmcgKnJpbmcgPSAmYW1wO2V0aC0mZ3Q7dHhfcmluZzs8YnI+DQrCoCDCoCDCoCDCoCBzdHJ1 Y3QgZGltX3NhbXBsZSBkaW1fc2FtcGxlID0ge307PGJyPg0KLcKgIMKgIMKgIMKgdW5zaWduZWQg aW50IGRvbmVbTVRLX01BWF9ERVZTXTs8YnI+DQotwqAgwqAgwqAgwqB1bnNpZ25lZCBpbnQgYnl0 ZXNbTVRLX01BWF9ERVZTXTs8YnI+DQotwqAgwqAgwqAgwqBpbnQgdG90YWwgPSAwLCBpOzxicj4N Ci08YnI+DQotwqAgwqAgwqAgwqBtZW1zZXQoZG9uZSwgMCwgc2l6ZW9mKGRvbmUpKTs8YnI+DQot wqAgwqAgwqAgwqBtZW1zZXQoYnl0ZXMsIDAsIHNpemVvZihieXRlcykpOzxicj4NCivCoCDCoCDC oCDCoHN0cnVjdCBtdGtfcG9sbF9zdGF0ZSBzdGF0ZSA9IHt9Ozxicj4NCjxicj4NCsKgIMKgIMKg IMKgIGlmIChNVEtfSEFTX0NBUFMoZXRoLSZndDtzb2MtJmd0O2NhcHMsIE1US19RRE1BKSk8YnI+ DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBidWRnZXQgPSBtdGtfcG9sbF90eF9xZG1hKGV0aCwg YnVkZ2V0LCBkb25lLCBieXRlcyk7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnVkZ2V0 ID0gbXRrX3BvbGxfdHhfcWRtYShldGgsIGJ1ZGdldCwgJmFtcDtzdGF0ZSk7PGJyPg0KwqAgwqAg wqAgwqAgZWxzZTxicj4NCi3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJ1ZGdldCA9IG10a19wb2xs X3R4X3BkbWEoZXRoLCBidWRnZXQsIGRvbmUsIGJ5dGVzKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBidWRnZXQgPSBtdGtfcG9sbF90eF9wZG1hKGV0aCwgYnVkZ2V0LCAmYW1wO3N0YXRl KTs8YnI+DQo8YnI+DQotwqAgwqAgwqAgwqBmb3IgKGkgPSAwOyBpICZsdDsgTVRLX01BQ19DT1VO VDsgaSsrKSB7PGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKCFldGgtJmd0O25ldGRl dltpXSB8fCAhZG9uZVtpXSk8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqBjb250aW51ZTs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBuZXRkZXZfY29tcGxldGVk X3F1ZXVlKGV0aC0mZ3Q7bmV0ZGV2W2ldLCBkb25lW2ldLCBieXRlc1tpXSk7PGJyPg0KLcKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgdG90YWwgKz0gZG9uZVtpXTs8YnI+DQotwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBldGgtJmd0O3R4X3BhY2tldHMgKz0gZG9uZVtpXTs8YnI+DQotwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqBldGgtJmd0O3R4X2J5dGVzICs9IGJ5dGVzW2ldOzxicj4NCi3CoCDCoCDCoCDC oH08YnI+DQorwqAgwqAgwqAgwqBpZiAoc3RhdGUudHhxKTxicj4NCivCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoG5ldGRldl90eF9jb21wbGV0ZWRfcXVldWUoc3RhdGUudHhxLCBzdGF0ZS5kb25lLCBz dGF0ZS5ieXRlcyk7PGJyPg0KPGJyPg0KwqAgwqAgwqAgwqAgZGltX3VwZGF0ZV9zYW1wbGUoZXRo LSZndDt0eF9ldmVudHMsIGV0aC0mZ3Q7dHhfcGFja2V0cywgZXRoLSZndDt0eF9ieXRlcyw8YnI+ DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAmYW1wO2RpbV9zYW1wbGUp Ozxicj4NCkBAIC0yMTIzLDcgKzIyMjEsNyBAQCBzdGF0aWMgaW50IG10a19wb2xsX3R4KHN0cnVj dCBtdGtfZXRoICpldGgsIGludCBidWRnZXQpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgKGF0b21p Y19yZWFkKCZhbXA7cmluZy0mZ3Q7ZnJlZV9jb3VudCkgJmd0OyByaW5nLSZndDt0aHJlc2gpKTxi cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG10a193YWtlX3F1ZXVlKGV0aCk7PGJyPg0KPGJy Pg0KLcKgIMKgIMKgIMKgcmV0dXJuIHRvdGFsOzxicj4NCivCoCDCoCDCoCDCoHJldHVybiBzdGF0 ZS50b3RhbDs8YnI+DQrCoH08YnI+DQo8YnI+DQrCoHN0YXRpYyB2b2lkIG10a19oYW5kbGVfc3Rh dHVzX2lycShzdHJ1Y3QgbXRrX2V0aCAqZXRoKTxicj4NCkBAIC0yMjA5LDYgKzIzMDcsNyBAQCBz dGF0aWMgaW50IG10a190eF9hbGxvYyhzdHJ1Y3QgbXRrX2V0aCAqZXRoKTxicj4NCsKgIMKgIMKg IMKgIGludCBpLCBzeiA9IHNvYy0mZ3Q7dHhyeC50eGRfc2l6ZTs8YnI+DQrCoCDCoCDCoCDCoCBz dHJ1Y3QgbXRrX3R4X2RtYV92MiAqdHhkOzxicj4NCsKgIMKgIMKgIMKgIGludCByaW5nX3NpemU7 PGJyPg0KK8KgIMKgIMKgIMKgdTMyIG9mcywgdmFsOzxicj4NCjxicj4NCsKgIMKgIMKgIMKgIGlm IChNVEtfSEFTX0NBUFMoc29jLSZndDtjYXBzLCBNVEtfUURNQSkpPGJyPg0KwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgcmluZ19zaXplID0gTVRLX1FETUFfUklOR19TSVpFOzxicj4NCkBAIC0yMjc2 LDggKzIzNzUsMjUgQEAgc3RhdGljIGludCBtdGtfdHhfYWxsb2Moc3RydWN0IG10a19ldGggKmV0 aCk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByaW5nLSZndDtwaHlz ICsgKChyaW5nX3NpemUgLSAxKSAqIHN6KSw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCBzb2MtJmd0O3JlZ19tYXAtJmd0O3FkbWEuY3J4X3B0cik7PGJyPg0KwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgbXRrX3czMihldGgsIHJpbmctJmd0O2xhc3RfZnJlZV9wdHIsIHNv Yy0mZ3Q7cmVnX21hcC0mZ3Q7cWRtYS5kcnhfcHRyKTs8YnI+DQotwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBtdGtfdzMyKGV0aCwgKFFETUFfUkVTX1RIUkVTICZsdDsmbHQ7IDgpIHwgUURNQV9SRVNf VEhSRVMsPGJyPg0KLcKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgc29jLSZndDty ZWdfbWFwLSZndDtxZG1hLnF0eF9jZmcpOzxicj4NCis8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqBmb3IgKGkgPSAwLCBvZnMgPSAwOyBpICZsdDsgTVRLX1FETUFfTlVNX1FVRVVFUzsgaSsr KSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdmFsID0gKFFETUFf UkVTX1RIUkVTICZsdDsmbHQ7IDgpIHwgUURNQV9SRVNfVEhSRVM7PGJyPg0KK8KgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbXRrX3czMihldGgsIHZhbCwgc29jLSZndDtyZWdfbWFw LSZndDtxZG1hLnF0eF9jZmcgKyBvZnMpOzxicj4NCis8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqB2YWwgPSBNVEtfUVRYX1NDSF9NSU5fUkFURV9FTiB8PGJyPg0KK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogbWluaW11bTogMTAg TWJwcyAqLzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oEZJRUxEX1BSRVAoTVRLX1FUWF9TQ0hfTUlOX1JBVEVfTUFOLCAxKSB8PGJyPg0KK8KgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgRklFTERfUFJFUChNVEtfUVRYX1ND SF9NSU5fUkFURV9FWFAsIDQpIHw8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBNVEtfUVRYX1NDSF9MRUFLWV9CVUNLRVRfU0laRTs8YnI+DQorwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoIU1US19IQVNfQ0FQUyhldGgtJmd0O3Nv Yy0mZ3Q7Y2FwcywgTVRLX05FVFNZU19WMikpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdmFsIHw9IE1US19RVFhfU0NIX0xFQUtZX0JVQ0tFVF9F Tjs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBtdGtfdzMyKGV0aCwg dmFsLCBzb2MtJmd0O3JlZ19tYXAtJmd0O3FkbWEucXR4X3NjaCArIG9mcyk7PGJyPg0KK8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgb2ZzICs9IE1US19RVFhfT0ZGU0VUOzxicj4N CivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB2 YWwgPSBNVEtfUURNQV9UWF9TQ0hfTUFYX1dGUSB8IChNVEtfUURNQV9UWF9TQ0hfTUFYX1dGUSAm bHQ7Jmx0OyAxNik7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbXRrX3czMihldGgsIHZh bCwgc29jLSZndDtyZWdfbWFwLSZndDtxZG1hLnR4X3NjaF9yYXRlKTs8YnI+DQorwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqBpZiAoTVRLX0hBU19DQVBTKGV0aC0mZ3Q7c29jLSZndDtjYXBzLCBNVEtf TkVUU1lTX1YyKSk8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBtdGtf dzMyKGV0aCwgdmFsLCBzb2MtJmd0O3JlZ19tYXAtJmd0O3FkbWEudHhfc2NoX3JhdGUgKyA0KTs8 YnI+DQrCoCDCoCDCoCDCoCB9IGVsc2Ugezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG10 a193MzIoZXRoLCByaW5nLSZndDtwaHlzX3BkbWEsIE1UNzYyOF9UWF9CQVNFX1BUUjApOzxicj4N CsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG10a193MzIoZXRoLCByaW5nX3NpemUsIE1UNzYyOF9U WF9NQVhfQ05UMCk7PGJyPg0KQEAgLTI5NTcsNyArMzA3Myw3IEBAIHN0YXRpYyBpbnQgbXRrX3N0 YXJ0X2RtYShzdHJ1Y3QgbXRrX2V0aCAqZXRoKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IGlmIChNVEtfSEFTX0NBUFMoZXRoLSZndDtzb2MtJmd0O2NhcHMsIE1US19ORVRTWVNfVjIpKTxi cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHZhbCB8PSBNVEtfTVVUTElf Q05UIHwgTVRLX1JFU1ZfQlVGIHw8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoE1US19XQ09NUF9FTiB8IE1US19ETUFEX1dSX1dET05FIHw8YnI+DQot wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgTVRLX0NIS19ERE9O RV9FTjs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg TVRLX0NIS19ERE9ORV9FTiB8IE1US19MRUFLWV9CVUNLRVRfRU47PGJyPg0KwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgZWxzZTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IHZhbCB8PSBNVEtfUlhfQlRfMzJEV09SRFM7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg bXRrX3czMihldGgsIHZhbCwgcmVnX21hcC0mZ3Q7cWRtYS5nbG9fY2ZnKTs8YnI+DQpAQCAtMzAx NCw2ICszMTMwLDQ1IEBAIHN0YXRpYyBib29sIG10a191c2VzX2RzYShzdHJ1Y3QgbmV0X2Rldmlj ZSAqZGV2KTxicj4NCsKgI2VuZGlmPGJyPg0KwqB9PGJyPg0KPGJyPg0KK3N0YXRpYyBpbnQgbXRr X2RldmljZV9ldmVudChzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm4sIHVuc2lnbmVkIGxvbmcgZXZl bnQsIHZvaWQgKnB0cik8YnI+DQorezxicj4NCivCoCDCoCDCoCDCoHN0cnVjdCBtdGtfbWFjICpt YWMgPSBjb250YWluZXJfb2Yobiwgc3RydWN0IG10a19tYWMsIGRldmljZV9ub3RpZmllcik7PGJy Pg0KK8KgIMKgIMKgIMKgc3RydWN0IG10a19ldGggKmV0aCA9IG1hYy0mZ3Q7aHc7PGJyPg0KK8Kg IMKgIMKgIMKgc3RydWN0IG5ldF9kZXZpY2UgKmRldiA9IG5ldGRldl9ub3RpZmllcl9pbmZvX3Rv X2RldihwdHIpOzxicj4NCivCoCDCoCDCoCDCoHN0cnVjdCBldGh0b29sX2xpbmtfa3NldHRpbmdz IHM7PGJyPg0KK8KgIMKgIMKgIMKgc3RydWN0IG5ldF9kZXZpY2UgKmxkZXY7PGJyPg0KK8KgIMKg IMKgIMKgc3RydWN0IGxpc3RfaGVhZCAqaXRlcjs8YnI+DQorwqAgwqAgwqAgwqBzdHJ1Y3QgZHNh X3BvcnQgKmRwOzxicj4NCis8YnI+DQorwqAgwqAgwqAgwqBpZiAoZXZlbnQgIT0gTkVUREVWX0NI QU5HRSk8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gTk9USUZZX0RPTkU7PGJy Pg0KKzxicj4NCivCoCDCoCDCoCDCoG5ldGRldl9mb3JfZWFjaF9sb3dlcl9kZXYoZGV2LCBsZGV2 LCBpdGVyKSB7PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKG5ldGRldl9wcml2KGxk ZXYpID09IG1hYyk8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBnb3Rv IGZvdW5kOzxicj4NCivCoCDCoCDCoCDCoH08YnI+DQorPGJyPg0KK8KgIMKgIMKgIMKgcmV0dXJu IE5PVElGWV9ET05FOzxicj4NCis8YnI+DQorZm91bmQ6PGJyPg0KK8KgIMKgIMKgIMKgaWYgKCFk c2Ffc2xhdmVfZGV2X2NoZWNrKGRldikpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0 dXJuIE5PVElGWV9ET05FOzxicj4NCis8YnI+DQorwqAgwqAgwqAgwqBpZiAoX19ldGh0b29sX2dl dF9saW5rX2tzZXR0aW5ncyhkZXYsICZhbXA7cykpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKg IMKgcmV0dXJuIE5PVElGWV9ET05FOzxicj4NCis8YnI+DQorwqAgwqAgwqAgwqBpZiAocy5iYXNl LnNwZWVkID09IDAgfHwgcy5iYXNlLnNwZWVkID09ICgoX191MzIpLTEpKTxicj4NCivCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoHJldHVybiBOT1RJRllfRE9ORTs8YnI+DQorPGJyPg0KK8KgIMKgIMKg IMKgZHAgPSBkc2FfcG9ydF9mcm9tX25ldGRldihkZXYpOzxicj4NCivCoCDCoCDCoCDCoGlmIChk cC0mZ3Q7aW5kZXggJmd0Oz0gTVRLX1FETUFfTlVNX1FVRVVFUyk8YnI+DQorwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqByZXR1cm4gTk9USUZZX0RPTkU7PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoG10 a19zZXRfcXVldWVfc3BlZWQoZXRoLCBkcC0mZ3Q7aW5kZXggKyAzLCBzLmJhc2Uuc3BlZWQpOzxi cj4NCis8YnI+DQorwqAgwqAgwqAgwqByZXR1cm4gTk9USUZZX0RPTkU7PGJyPg0KK308YnI+DQor PGJyPg0KwqBzdGF0aWMgaW50IG10a19vcGVuKHN0cnVjdCBuZXRfZGV2aWNlICpkZXYpPGJyPg0K wqB7PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IG10a19tYWMgKm1hYyA9IG5ldGRldl9wcml2KGRl dik7PGJyPg0KQEAgLTMwNzgsNyArMzIzMyw4IEBAIHN0YXRpYyBpbnQgbXRrX29wZW4oc3RydWN0 IG5ldF9kZXZpY2UgKmRldik8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZWZjb3VudF9p bmMoJmFtcDtldGgtJmd0O2RtYV9yZWZjbnQpOzxicj4NCjxicj4NCsKgIMKgIMKgIMKgIHBoeWxp bmtfc3RhcnQobWFjLSZndDtwaHlsaW5rKTs8YnI+DQotwqAgwqAgwqAgwqBuZXRpZl9zdGFydF9x dWV1ZShkZXYpOzxicj4NCivCoCDCoCDCoCDCoG5ldGlmX3R4X3N0YXJ0X2FsbF9xdWV1ZXMoZGV2 KTs8YnI+DQorPGJyPg0KwqAgwqAgwqAgwqAgcmV0dXJuIDA7PGJyPg0KwqB9PGJyPg0KPGJyPg0K QEAgLTM2MDcsOCArMzc2MywxMiBAQCBzdGF0aWMgaW50IG10a191bnJlZ19kZXYoc3RydWN0IG10 a19ldGggKmV0aCk8YnI+DQrCoCDCoCDCoCDCoCBpbnQgaTs8YnI+DQo8YnI+DQrCoCDCoCDCoCDC oCBmb3IgKGkgPSAwOyBpICZsdDsgTVRLX01BQ19DT1VOVDsgaSsrKSB7PGJyPg0KK8KgIMKgIMKg IMKgIMKgIMKgIMKgIMKgc3RydWN0IG10a19tYWMgKm1hYzs8YnI+DQrCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCBpZiAoIWV0aC0mZ3Q7bmV0ZGV2W2ldKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIGNvbnRpbnVlOzxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG1h YyA9IG5ldGRldl9wcml2KGV0aC0mZ3Q7bmV0ZGV2W2ldKTs8YnI+DQorwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqBpZiAoTVRLX0hBU19DQVBTKGV0aC0mZ3Q7c29jLSZndDtjYXBzLCBNVEtfUURNQSkp PGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdW5yZWdpc3Rlcl9uZXRk ZXZpY2Vfbm90aWZpZXIoJmFtcDttYWMtJmd0O2RldmljZV9ub3RpZmllcik7PGJyPg0KwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgdW5yZWdpc3Rlcl9uZXRkZXYoZXRoLSZndDtuZXRkZXZbaV0pOzxi cj4NCsKgIMKgIMKgIMKgIH08YnI+DQo8YnI+DQpAQCAtMzgyNCw2ICszOTg0LDIzIEBAIHN0YXRp YyBpbnQgbXRrX3NldF9yeG5mYyhzdHJ1Y3QgbmV0X2RldmljZSAqZGV2LCBzdHJ1Y3QgZXRodG9v bF9yeG5mYyAqY21kKTxicj4NCsKgIMKgIMKgIMKgIHJldHVybiByZXQ7PGJyPg0KwqB9PGJyPg0K PGJyPg0KK3N0YXRpYyB1MTYgbXRrX3NlbGVjdF9xdWV1ZShzdHJ1Y3QgbmV0X2RldmljZSAqZGV2 LCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLDxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoHN0cnVjdCBuZXRfZGV2aWNlICpzYl9kZXYpPGJyPg0KK3s8YnI+DQorwqAg wqAgwqAgwqBzdHJ1Y3QgbXRrX21hYyAqbWFjID0gbmV0ZGV2X3ByaXYoZGV2KTs8YnI+DQorwqAg wqAgwqAgwqB1bnNpZ25lZCBpbnQgcXVldWUgPSAwOzxicj4NCis8YnI+DQorwqAgwqAgwqAgwqBp ZiAobmV0ZGV2X3VzZXNfZHNhKGRldikpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcXVl dWUgPSBza2JfZ2V0X3F1ZXVlX21hcHBpbmcoc2tiKSArIDM7PGJyPg0KK8KgIMKgIMKgIMKgZWxz ZTxicj4NCivCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHF1ZXVlID0gbWFjLSZndDtpZDs8YnI+DQor PGJyPg0KK8KgIMKgIMKgIMKgaWYgKHF1ZXVlICZndDs9IGRldi0mZ3Q7bnVtX3R4X3F1ZXVlcyk8 YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBxdWV1ZSA9IDA7PGJyPg0KKzxicj4NCivCoCDC oCDCoCDCoHJldHVybiBxdWV1ZTs8YnI+DQorfTxicj4NCis8YnI+DQrCoHN0YXRpYyBjb25zdCBz dHJ1Y3QgZXRodG9vbF9vcHMgbXRrX2V0aHRvb2xfb3BzID0gezxicj4NCsKgIMKgIMKgIMKgIC5n ZXRfbGlua19rc2V0dGluZ3PCoCDCoCDCoD0gbXRrX2dldF9saW5rX2tzZXR0aW5ncyw8YnI+DQrC oCDCoCDCoCDCoCAuc2V0X2xpbmtfa3NldHRpbmdzwqAgwqAgwqA9IG10a19zZXRfbGlua19rc2V0 dGluZ3MsPGJyPg0KQEAgLTM4NTksNiArNDAzNiw3IEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3QgbmV0 X2RldmljZV9vcHMgbXRrX25ldGRldl9vcHMgPSB7PGJyPg0KwqAgwqAgwqAgwqAgLm5kb19zZXR1 cF90Y8KgIMKgIMKgIMKgIMKgIMKgPSBtdGtfZXRoX3NldHVwX3RjLDxicj4NCsKgIMKgIMKgIMKg IC5uZG9fYnBmwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgPSBtdGtfeGRwLDxicj4NCsKgIMKgIMKg IMKgIC5uZG9feGRwX3htaXTCoCDCoCDCoCDCoCDCoCDCoD0gbXRrX3hkcF94bWl0LDxicj4NCivC oCDCoCDCoCDCoC5uZG9fc2VsZWN0X3F1ZXVlwqAgwqAgwqAgwqA9IG10a19zZWxlY3RfcXVldWUs PGJyPg0KwqB9Ozxicj4NCjxicj4NCsKgc3RhdGljIGludCBtdGtfYWRkX21hYyhzdHJ1Y3QgbXRr X2V0aCAqZXRoLCBzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wKTxicj4NCkBAIC0zODY4LDYgKzQwNDYs NyBAQCBzdGF0aWMgaW50IG10a19hZGRfbWFjKHN0cnVjdCBtdGtfZXRoICpldGgsIHN0cnVjdCBk ZXZpY2Vfbm9kZSAqbnApPGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IHBoeWxpbmsgKnBoeWxpbms7 PGJyPg0KwqAgwqAgwqAgwqAgc3RydWN0IG10a19tYWMgKm1hYzs8YnI+DQrCoCDCoCDCoCDCoCBp bnQgaWQsIGVycjs8YnI+DQorwqAgwqAgwqAgwqBpbnQgdHhxcyA9IDE7PGJyPg0KPGJyPg0KwqAg wqAgwqAgwqAgaWYgKCFfaWQpIHs8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkZXZfZXJy KGV0aC0mZ3Q7ZGV2LCAmcXVvdDttaXNzaW5nIG1hYyBpZFxuJnF1b3Q7KTs8YnI+DQpAQCAtMzg4 NSw3ICs0MDY0LDEwIEBAIHN0YXRpYyBpbnQgbXRrX2FkZF9tYWMoc3RydWN0IG10a19ldGggKmV0 aCwgc3RydWN0IGRldmljZV9ub2RlICpucCk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBy ZXR1cm4gLUVJTlZBTDs8YnI+DQrCoCDCoCDCoCDCoCB9PGJyPg0KPGJyPg0KLcKgIMKgIMKgIMKg ZXRoLSZndDtuZXRkZXZbaWRdID0gYWxsb2NfZXRoZXJkZXYoc2l6ZW9mKCptYWMpKTs8YnI+DQor wqAgwqAgwqAgwqBpZiAoTVRLX0hBU19DQVBTKGV0aC0mZ3Q7c29jLSZndDtjYXBzLCBNVEtfUURN QSkpPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdHhxcyA9IE1US19RRE1BX05VTV9RVUVV RVM7PGJyPg0KKzxicj4NCivCoCDCoCDCoCDCoGV0aC0mZ3Q7bmV0ZGV2W2lkXSA9IGFsbG9jX2V0 aGVyZGV2X21xcyhzaXplb2YoKm1hYyksIHR4cXMsIDEpOzxicj4NCsKgIMKgIMKgIMKgIGlmICgh ZXRoLSZndDtuZXRkZXZbaWRdKSB7PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZGV2X2Vy cihldGgtJmd0O2RldiwgJnF1b3Q7YWxsb2NfZXRoZXJkZXYgZmFpbGVkXG4mcXVvdDspOzxicj4N CsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiAtRU5PTUVNOzxicj4NCkBAIC0zOTgyLDYg KzQxNjQsMTEgQEAgc3RhdGljIGludCBtdGtfYWRkX21hYyhzdHJ1Y3QgbXRrX2V0aCAqZXRoLCBz dHJ1Y3QgZGV2aWNlX25vZGUgKm5wKTxicj4NCsKgIMKgIMKgIMKgIGVsc2U8YnI+DQrCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCBldGgtJmd0O25ldGRldltpZF0tJmd0O21heF9tdHUgPSBNVEtfTUFY X1JYX0xFTkdUSF8ySyAtIE1US19SWF9FVEhfSExFTjs8YnI+DQo8YnI+DQorwqAgwqAgwqAgwqBp ZiAoTVRLX0hBU19DQVBTKGV0aC0mZ3Q7c29jLSZndDtjYXBzLCBNVEtfUURNQSkpIHs8YnI+DQor wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBtYWMtJmd0O2RldmljZV9ub3RpZmllci5ub3RpZmllcl9j YWxsID0gbXRrX2RldmljZV9ldmVudDs8YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZWdp c3Rlcl9uZXRkZXZpY2Vfbm90aWZpZXIoJmFtcDttYWMtJmd0O2RldmljZV9ub3RpZmllcik7PGJy Pg0KK8KgIMKgIMKgIMKgfTxicj4NCis8YnI+DQrCoCDCoCDCoCDCoCByZXR1cm4gMDs8YnI+DQo8 YnI+DQrCoGZyZWVfbmV0ZGV2Ojxicj4NCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC9ldGhlcm5l dC9tZWRpYXRlay9tdGtfZXRoX3NvYy5oIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvbWVkaWF0ZWsv bXRrX2V0aF9zb2MuaDxicj4NCmluZGV4IGVhYWEwYzY3ZWYyYS4uMTU4MWViYTA1M2FiIDEwMDY0 NDxicj4NCi0tLSBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L21lZGlhdGVrL210a19ldGhfc29jLmg8 YnI+DQorKysgYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9tZWRpYXRlay9tdGtfZXRoX3NvYy5oPGJy Pg0KQEAgLTI1LDYgKzI1LDcgQEA8YnI+DQrCoCNkZWZpbmUgTVRLX01BWF9EU0FfUE9SVFPCoCDC oCDCoCA3PGJyPg0KwqAjZGVmaW5lIE1US19EU0FfUE9SVF9NQVNLwqAgwqAgwqAgR0VOTUFTSygy LCAwKTxicj4NCjxicj4NCisjZGVmaW5lIE1US19RRE1BX05VTV9RVUVVRVPCoCDCoCAxNjxicj4N CsKgI2RlZmluZSBNVEtfUURNQV9QQUdFX1NJWkXCoCDCoCDCoDIwNDg8YnI+DQrCoCNkZWZpbmUg TVRLX01BWF9SWF9MRU5HVEjCoCDCoCDCoCAxNTM2PGJyPg0KwqAjZGVmaW5lIE1US19NQVhfUlhf TEVOR1RIXzJLwqAgwqAyMDQ4PGJyPg0KQEAgLTIxMCw4ICsyMTEsMjYgQEA8YnI+DQrCoCNkZWZp bmUgTVRLX1JJTkdfTUFYX0FHR19DTlRfSMKgIMKgIMKgIMKgIMKgKChNVEtfSFdfTFJPX01BWF9B R0dfQ05UICZndDsmZ3Q7IDYpICZhbXA7IDB4Myk8YnI+DQo8YnI+DQrCoC8qIFFETUEgVFggUXVl dWUgQ29uZmlndXJhdGlvbiBSZWdpc3RlcnMgKi88YnI+DQorI2RlZmluZSBNVEtfUVRYX09GRlNF VMKgIMKgIMKgIMKgIMKgMHgxMDxicj4NCsKgI2RlZmluZSBRRE1BX1JFU19USFJFU8KgIMKgIMKg IMKgIMKgNDxicj4NCjxicj4NCisvKiBRRE1BIFR4IFF1ZXVlIFNjaGVkdWxlciBDb25maWd1cmF0 aW9uIFJlZ2lzdGVycyAqLzxicj4NCisjZGVmaW5lIE1US19RVFhfU0NIX1RYX1NFTMKgIMKgIMKg IMKgIMKgIMKgIMKgQklUKDMxKTxicj4NCisjZGVmaW5lIE1US19RVFhfU0NIX1RYX1NFTF9WMsKg IMKgIMKgIMKgIMKgIEdFTk1BU0soMzEsIDMwKTxicj4NCis8YnI+DQorI2RlZmluZSBNVEtfUVRY X1NDSF9MRUFLWV9CVUNLRVRfRU7CoCDCoCBCSVQoMzApPGJyPg0KKyNkZWZpbmUgTVRLX1FUWF9T Q0hfTEVBS1lfQlVDS0VUX1NJWkXCoCBHRU5NQVNLKDI5LCAyOCk8YnI+DQorI2RlZmluZSBNVEtf UVRYX1NDSF9NSU5fUkFURV9FTsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEJJVCgyNyk8YnI+DQor I2RlZmluZSBNVEtfUVRYX1NDSF9NSU5fUkFURV9NQU7CoCDCoCDCoCDCoEdFTk1BU0soMjYsIDIw KTxicj4NCisjZGVmaW5lIE1US19RVFhfU0NIX01JTl9SQVRFX0VYUMKgIMKgIMKgIMKgR0VOTUFT SygxOSwgMTYpPGJyPg0KKyNkZWZpbmUgTVRLX1FUWF9TQ0hfTUFYX1JBVEVfV0VJR0hUwqAgwqAg R0VOTUFTSygxNSwgMTIpPGJyPg0KKyNkZWZpbmUgTVRLX1FUWF9TQ0hfTUFYX1JBVEVfRU7CoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCBCSVQoMTEpPGJyPg0KKyNkZWZpbmUgTVRLX1FUWF9TQ0hfTUFY X1JBVEVfTUFOwqAgwqAgwqAgwqBHRU5NQVNLKDEwLCA0KTxicj4NCisjZGVmaW5lIE1US19RVFhf U0NIX01BWF9SQVRFX0VYUMKgIMKgIMKgIMKgR0VOTUFTSygzLCAwKTxicj4NCis8YnI+DQorLyog UURNQSBUWCBTY2hlZHVsZXIgUmF0ZSBDb250cm9sIFJlZ2lzdGVyICovPGJyPg0KKyNkZWZpbmUg TVRLX1FETUFfVFhfU0NIX01BWF9XRlHCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBCSVQoMTUpPGJy Pg0KKzxicj4NCsKgLyogUURNQSBHbG9iYWwgQ29uZmlndXJhdGlvbiBSZWdpc3RlciAqLzxicj4N CsKgI2RlZmluZSBNVEtfUlhfMkJfT0ZGU0VUwqAgwqAgwqAgwqBCSVQoMzEpPGJyPg0KwqAjZGVm aW5lIE1US19SWF9CVF8zMkRXT1JEU8KgIMKgIMKgKDMgJmx0OyZsdDsgMTEpPGJyPg0KQEAgLTIz MCw2ICsyNDksNyBAQDxicj4NCsKgI2RlZmluZSBNVEtfV0NPTVBfRU7CoCDCoCDCoCDCoCDCoCDC oEJJVCgyNCk8YnI+DQrCoCNkZWZpbmUgTVRLX1JFU1ZfQlVGwqAgwqAgwqAgwqAgwqAgwqAoMHg0 MCAmbHQ7Jmx0OyAxNik8YnI+DQrCoCNkZWZpbmUgTVRLX01VVExJX0NOVMKgIMKgIMKgIMKgIMKg ICgweDQgJmx0OyZsdDsgMTIpPGJyPg0KKyNkZWZpbmUgTVRLX0xFQUtZX0JVQ0tFVF9FTsKgIMKg IEJJVCgxMSk8YnI+DQo8YnI+DQrCoC8qIFFETUEgRmxvdyBDb250cm9sIFJlZ2lzdGVyICovPGJy Pg0KwqAjZGVmaW5lIEZDX1RIUkVTX0RST1BfTU9ERcKgIMKgIMKgQklUKDIwKTxicj4NCkBAIC0y NTgsOCArMjc4LDYgQEA8YnI+DQrCoCNkZWZpbmUgTVRLX1NUQVRfT0ZGU0VUwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgMHg0MDxicj4NCjxicj4NCsKgLyogUURNQSBUWCBOVU0gKi88YnI+DQotI2Rl ZmluZSBNVEtfUURNQV9UWF9OVU3CoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAxNjxicj4NCi0jZGVm aW5lIE1US19RRE1BX1RYX01BU0vCoCDCoCDCoCDCoChNVEtfUURNQV9UWF9OVU0gLSAxKTxicj4N CsKgI2RlZmluZSBRSURfQklUU19WMih4KcKgIMKgIMKgIMKgIMKgKCgoeCkgJmFtcDsgMHgzZikg Jmx0OyZsdDsgMTYpPGJyPg0KwqAjZGVmaW5lIE1US19RRE1BX0dNQUMyX1FJRMKgIMKgIMKgODxi cj4NCjxicj4NCkBAIC0yODksNiArMzA3LDcgQEA8YnI+DQrCoCNkZWZpbmUgVFhfRE1BX1BMRU4w KHgpwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKCgoeCkgJmFtcDsgZXRoLSZndDtzb2MtJmd0O3R4 cnguZG1hX21heF9sZW4pICZsdDsmbHQ7IGV0aC0mZ3Q7c29jLSZndDt0eHJ4LmRtYV9sZW5fb2Zm c2V0KTxicj4NCsKgI2RlZmluZSBUWF9ETUFfUExFTjEoeCnCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCAoKHgpICZhbXA7IGV0aC0mZ3Q7c29jLSZndDt0eHJ4LmRtYV9tYXhfbGVuKTxicj4NCsKgI2Rl ZmluZSBUWF9ETUFfU1dDwqAgwqAgwqAgwqAgwqAgwqAgwqBCSVQoMTQpPGJyPg0KKyNkZWZpbmUg VFhfRE1BX1BRSUTCoCDCoCDCoCDCoCDCoCDCoCBHRU5NQVNLKDMsIDApPGJyPg0KPGJyPg0KwqAv KiBQRE1BIG9uIE1UNzYyOCAqLzxicj4NCsKgI2RlZmluZSBUWF9ETUFfRE9ORcKgIMKgIMKgIMKg IMKgIMKgIEJJVCgzMSk8YnI+DQpAQCAtOTQ3LDYgKzk2Niw3IEBAIHN0cnVjdCBtdGtfcmVnX21h cCB7PGJyPg0KwqAgwqAgwqAgwqAgfSBwZG1hOzxicj4NCsKgIMKgIMKgIMKgIHN0cnVjdCB7PGJy Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdTMywqAgwqAgwqBxdHhfY2ZnO8KgIMKgIMKgIMKg IC8qIHR4IHF1ZXVlIGNvbmZpZ3VyYXRpb24gKi88YnI+DQorwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqB1MzLCoCDCoCDCoHF0eF9zY2g7wqAgwqAgwqAgwqAgLyogdHggcXVldWUgc2NoZWR1bGVyIGNv bmZpZ3VyYXRpb24gKi88YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB1MzLCoCDCoCDCoHJ4 X3B0cjvCoCDCoCDCoCDCoCDCoC8qIHJ4IGJhc2UgcG9pbnRlciAqLzxicj4NCsKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIHUzMsKgIMKgIMKgcnhfY250X2NmZzvCoCDCoCDCoC8qIHJ4IG1heCBjb3Vu dCBjb25maWd1cmF0aW9uICovPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdTMywqAgwqAg wqBxY3J4X3B0cjvCoCDCoCDCoCDCoC8qIHJ4IGNwdSBwb2ludGVyICovPGJyPg0KQEAgLTk2NCw2 ICs5ODQsNyBAQCBzdHJ1Y3QgbXRrX3JlZ19tYXAgezxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIHUzMsKgIMKgIMKgZnFfdGFpbDvCoCDCoCDCoCDCoCAvKiBmcSB0YWlsIHBvaW50ZXIgKi88 YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB1MzLCoCDCoCDCoGZxX2NvdW50O8KgIMKgIMKg IMKgLyogZnEgZnJlZSBwYWdlIGNvdW50ICovPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg dTMywqAgwqAgwqBmcV9ibGVuO8KgIMKgIMKgIMKgIC8qIGZxIGZyZWUgcGFnZSBidWZmZXIgbGVu Z3RoICovPGJyPg0KK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdTMywqAgwqAgwqB0eF9zY2hfcmF0 ZTvCoCDCoCAvKiB0eCBzY2hlZHVsZXIgcmF0ZSBjb250cm9sIHJlZ2lzdGVycyAqLzxicj4NCsKg IMKgIMKgIMKgIH0gcWRtYTs8YnI+DQrCoCDCoCDCoCDCoCB1MzLCoCDCoCDCoGdkbTFfY250Ozxi cj4NCsKgIMKgIMKgIMKgIHUzMsKgIMKgIMKgZ2RtYV90b19wcGU7PGJyPg0KQEAgLTExNTcsNiAr MTE3OCw3IEBAIHN0cnVjdCBtdGtfbWFjIHs8YnI+DQrCoCDCoCDCoCDCoCBfX2JlMzLCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBod2xyb19pcFtNVEtfTUFYX0xST19JUF9D TlRdOzxicj4NCsKgIMKgIMKgIMKgIGludMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgaHdscm9faXBfY250Ozxicj4NCsKgIMKgIMKgIMKgIHVuc2lnbmVkIGludMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHN5c2NmZzA7PGJyPg0KK8KgIMKgIMKgIMKgc3Ry dWN0IG5vdGlmaWVyX2Jsb2NrwqAgwqAgwqAgwqAgwqAgwqBkZXZpY2Vfbm90aWZpZXI7PGJyPg0K wqB9Ozxicj4NCjxicj4NCsKgLyogdGhlIHN0cnVjdCBkZXNjcmliaW5nIHRoZSBTb0MuIHRoZXNl IGFyZSBkZWNsYXJlZCBpbiB0aGUgc29jX3h5ei5jIGZpbGVzICovPGJyPg0KLS0gPGJyPg0KMi4z OC4xPGJyPg0KPGJyPg0KPC9kaXY+DQo= --0000000000008ddea905ed9c2cb7--