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=-24.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 1DD30C43462 for ; Fri, 7 May 2021 14:01:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CCF23613C0 for ; Fri, 7 May 2021 14:01:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237435AbhEGOCp (ORCPT ); Fri, 7 May 2021 10:02:45 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:25788 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237371AbhEGOCQ (ORCPT ); Fri, 7 May 2021 10:02:16 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20210507140115euoutp02a10f8f375a9a4cb4991ff5dc81961cf2~8zaVIfve21924819248euoutp02y for ; Fri, 7 May 2021 14:01:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20210507140115euoutp02a10f8f375a9a4cb4991ff5dc81961cf2~8zaVIfve21924819248euoutp02y DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1620396075; bh=ny6IYZbd4LSHmOSrccvVvvtDUZwgDQtJI4viqmbR7nk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r9GVYiQ/4o/QHRmlDdGYuw0AGPzGnf1cSOlxooUP2V0goF0RjNMMTAhbcdyPPe8XG Dq2p4R9/m/tWONHYF06Jl59s777uwGTcOfKmd0BJe6Mv35a4kaANwL770JetVcKLQK UPDwdd8NlrYDaU7/At/C7SgHKOuq40rdHNrl6qNk= Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20210507140115eucas1p25cd3df26b201033c80b032b027c3c358~8zaUe8ojW2125021250eucas1p2m; Fri, 7 May 2021 14:01:15 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id B8.37.09444.A2845906; Fri, 7 May 2021 15:01:14 +0100 (BST) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20210507140114eucas1p23b94a5fdf2d50813999a6d4a9a44731f~8zaT2Er6R0929309293eucas1p23; Fri, 7 May 2021 14:01:14 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20210507140114eusmtrp1dcea52fee4ab85feffa5173186cc530e~8zaT1BmJg3065730657eusmtrp1S; Fri, 7 May 2021 14:01:14 +0000 (GMT) X-AuditID: cbfec7f4-dbdff700000024e4-ab-6095482acbaf Received: from eusmtip1.samsung.com ( [203.254.199.221]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id D5.49.08696.A2845906; Fri, 7 May 2021 15:01:14 +0100 (BST) Received: from localhost (unknown [106.120.51.46]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20210507140114eusmtip1b4c42f967ceef5facb75d6b868f7e2df~8zaTiaMkt2247722477eusmtip11; Fri, 7 May 2021 14:01:13 +0000 (GMT) From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= To: Andrew Lunn , jim.cromie@gmail.com, Heiner Kallweit , "David S. Miller" , Jakub Kicinski , Rob Herring , Kukjin Kim , Krzysztof Kozlowski , Russell King , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org Cc: =?UTF-8?q?Bart=C5=82omiej=20=C5=BBolnierkiewicz?= , Marek Szyprowski , =?UTF-8?q?=C5=81ukasz=20Stelmach?= Subject: [PATCH net-next v12 3/3] net: ax88796c: ASIX AX88796C SPI Ethernet Adapter Driver Date: Fri, 7 May 2021 16:01:10 +0200 Message-Id: <20210507140110.6323-4-l.stelmach@samsung.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210507140110.6323-1-l.stelmach@samsung.com> MIME-Version: 1.0 Organization: Samsung R&D Institute Poland Content-Transfer-Encoding: 8bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrCKsWRmVeSWpSXmKPExsWy7djP87paHlMTDJ6dNbE4f/cQs8XGGetZ Leacb2GxmH/kHKvFovczWC2uvb3DatH/+DWzxfnzG9gtLmzrY7W4eWgFo8Wmx9dYLS7vmsNm MeP8PiaLQ1P3MlqsPXKX3eLYAjGL1r1H2B0EPS5fu8jssWXlTSaPnbPusntsWtXJ5rF5Sb3H zh2fmTz6tqxi9Pi8SS6AI4rLJiU1J7MstUjfLoErY+q2HcwFG6ayVMxceI61gbFvB3MXIyeH hICJxKkjX1i6GLk4hARWMErc/LGWCcL5wijx/uAmdgjnM6PE37NtjDAtT6+3QVUtZ5TYcHgX G4TznFFiyvHp7CBVbAKOEv1LT7CCJEQE7jFLrG9/wAjiMAvsY5TYeW8K2HphgRiJ5+vnsYLY LAKqEs9m/wWzeQWsJJ4cn8AOsU9eon35djYQm1PAWuLBp7vsEDWCEidnPmEBsfkFtCTWNF0H s5mB6pu3zmYGWSYhsJ9TYtKORSwQg1wknn/5yQphC0u8Or4FaoGMxOnJPUA1HEB2vcTkSWYQ vT2MEtvm/IDqtZa4c+4XG0gNs4CmxPpd+hBhR4k9r7qYIVr5JG68FYQ4gU9i0rbpUGFeiY42 IYhqFYl1/XugBkpJ9L5awTiBUWkWkmdmIXlgFsKuBYzMqxjFU0uLc9NTi43yUsv1ihNzi0vz 0vWS83M3MQIT3ul/x7/sYFz+6qPeIUYmDsZDjBIczEoivKcXTU4Q4k1JrKxKLcqPLyrNSS0+ xCjNwaIkzpu0ZU28kEB6YklqdmpqQWoRTJaJg1OqgWmN7MXg/z2hZ5fI7mx9+XMLl1uP99X/ i3eui5J773Rg0ZLUuLNRN+rq7SoiZ9+tOylSuOjX7Tr78uC4O/6rNPiFO/RXRNkuY/1x9vPl ktlT2+4w5J5mOLCJe93Te7Mz3sQr50YuOa93eYL3HcmCZ0dEP23NFGFmdYq8N3d5dgiLauyX qLMcCupp5/eesbM7xu8guvTjIbvVUybfZHLfd1VtQaeE8OVfb3bNn8+j9nCNNMfr7YyRU3x3 Xoh352zqyPbkmrH+u9JK9hWzPk9tTnlzcrLbVvOI3EXVXxuuv9p8yOX96p3x7KE1hsYZy/c2 uh1sPiWtkS15ZS/bVPHfO3Sq15y5rhMYof3Q0Pn13ZV6SizFGYmGWsxFxYkAxEM64ucDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrMIsWRmVeSWpSXmKPExsVy+t/xu7paHlMTDGad57Y4f/cQs8XGGetZ Leacb2GxmH/kHKvFovczWC2uvb3DatH/+DWzxfnzG9gtLmzrY7W4eWgFo8Wmx9dYLS7vmsNm MeP8PiaLQ1P3MlqsPXKX3eLYAjGL1r1H2B0EPS5fu8jssWXlTSaPnbPusntsWtXJ5rF5Sb3H zh2fmTz6tqxi9Pi8SS6AI0rPpii/tCRVISO/uMRWKdrQwkjP0NJCz8jEUs/Q2DzWyshUSd/O JiU1J7MstUjfLkEvY+q2HcwFG6ayVMxceI61gbFvB3MXIyeHhICJxNPrbUxdjFwcQgJLGSW6 P95h6WLkAEpISaycmw5RIyzx51oXG0TNU0aJOcfnsIEk2AQcJfqXnmAFSYgIvGGWaLr3lh3E YRbYxyix/+hidpBJwgJREq07LUAaWARUJZ7N/ssKYvMKWEk8OT6BHWKDvET78u1gQzkFrCUe fLoLFhcCqpm4qZMJol5Q4uTMJ2DHMQuoS6yfJwQS5hfQkljTdJ0FxGYGGtO8dTbzBEahWUg6 ZiF0zEJStYCReRWjSGppcW56brGRXnFibnFpXrpecn7uJkZgbG879nPLDsaVrz7qHWJk4mA8 xCjBwawkwnt60eQEId6UxMqq1KL8+KLSnNTiQ4ymQJ9NZJYSTc4HJpe8knhDMwNTQxMzSwNT SzNjJXFekyNr4oUE0hNLUrNTUwtSi2D6mDg4pRqYNtiJbPdxdOPqST20PEPuptved9nM3899 284VdXLj0fbn7g27T38M+3RlTdWCm/+5uR8IFMzRv3Xd91Zt0MWUUAbDHQdv5lwKeO/jJno0 zd764Dyrgi0S60+/enR9u6/kBDUdoWk8Wh3Hu4Jf31Feplz7dn+RnmXbpz0dqvyHep0ytK+q 16+d4p1Z/CxULbPJSu26buyuB6nGkkWvl/5RYc/avZXHhuWq/5mp9Uc+L30cMslSxp0ly/pj nfz0w8ve1JlteMTTw+U0S32WlGz42onra7Lm3riiJzvjIL9b0DWBoicnD2mf+/Sqh1dw3fGt 7R/Xxx0tfFFrIrU/j0NkGd/sPNUP0ypO/njC9eT6MyWW4oxEQy3mouJEAA6HHyp2AwAA X-CMS-MailID: 20210507140114eucas1p23b94a5fdf2d50813999a6d4a9a44731f X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20210507140114eucas1p23b94a5fdf2d50813999a6d4a9a44731f X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20210507140114eucas1p23b94a5fdf2d50813999a6d4a9a44731f References: <20210507140110.6323-1-l.stelmach@samsung.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org ASIX AX88796[1] is a versatile ethernet adapter chip, that can be connected to a CPU with a 8/16-bit bus or with an SPI. This driver supports SPI connection. The driver has been ported from the vendor kernel for ARTIK5[2] boards. Several changes were made to adapt it to the current kernel which include: + updated DT configuration, + clock configuration moved to DT, + new timer, ethtool and gpio APIs, + dev_* instead of pr_* and custom printk() wrappers, + removed awkward vendor power managemtn. + introduced ethtool tunable to control SPI compression [1] https://www.asix.com.tw/products.php?op=pItemdetail&PItemID=104;65;86&PLine=65 [2] https://git.tizen.org/cgit/profile/common/platform/kernel/linux-3.10-artik/ The other ax88796 driver is for NE2000 compatible AX88796L chip. These chips are not compatible. Hence, two separate drivers are required. Signed-off-by: Łukasz Stelmach Reviewed-by: Andrew Lunn --- MAINTAINERS | 6 + drivers/net/ethernet/Kconfig | 1 + drivers/net/ethernet/Makefile | 1 + drivers/net/ethernet/asix/Kconfig | 35 + drivers/net/ethernet/asix/Makefile | 6 + drivers/net/ethernet/asix/ax88796c_ioctl.c | 239 ++++ drivers/net/ethernet/asix/ax88796c_ioctl.h | 26 + drivers/net/ethernet/asix/ax88796c_main.c | 1146 ++++++++++++++++++++ drivers/net/ethernet/asix/ax88796c_main.h | 568 ++++++++++ drivers/net/ethernet/asix/ax88796c_spi.c | 115 ++ drivers/net/ethernet/asix/ax88796c_spi.h | 69 ++ 11 files changed, 2212 insertions(+) create mode 100644 drivers/net/ethernet/asix/Kconfig create mode 100644 drivers/net/ethernet/asix/Makefile create mode 100644 drivers/net/ethernet/asix/ax88796c_ioctl.c create mode 100644 drivers/net/ethernet/asix/ax88796c_ioctl.h create mode 100644 drivers/net/ethernet/asix/ax88796c_main.c create mode 100644 drivers/net/ethernet/asix/ax88796c_main.h create mode 100644 drivers/net/ethernet/asix/ax88796c_spi.c create mode 100644 drivers/net/ethernet/asix/ax88796c_spi.h diff --git a/MAINTAINERS b/MAINTAINERS index 4796ccf9f871..5e3644f25406 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2814,6 +2814,12 @@ S: Maintained F: Documentation/hwmon/asc7621.rst F: drivers/hwmon/asc7621.c +ASIX AX88796C SPI ETHERNET ADAPTER +M: Łukasz Stelmach +S: Maintained +F: Documentation/devicetree/bindings/net/asix,ax88796c.yaml +F: drivers/net/ethernet/asix/ax88796c_* + ASPEED PINCTRL DRIVERS M: Andrew Jeffery L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index 1cdff1dca790..c4447274c9de 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig @@ -33,6 +33,7 @@ source "drivers/net/ethernet/apm/Kconfig" source "drivers/net/ethernet/apple/Kconfig" source "drivers/net/ethernet/aquantia/Kconfig" source "drivers/net/ethernet/arc/Kconfig" +source "drivers/net/ethernet/asix/Kconfig" source "drivers/net/ethernet/atheros/Kconfig" source "drivers/net/ethernet/broadcom/Kconfig" source "drivers/net/ethernet/brocade/Kconfig" diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index cb3f9084a21b..3d3d2b352304 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_NET_XGENE) += apm/ obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ obj-$(CONFIG_NET_VENDOR_AQUANTIA) += aquantia/ obj-$(CONFIG_NET_VENDOR_ARC) += arc/ +obj-$(CONFIG_NET_VENDOR_ASIX) += asix/ obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ obj-$(CONFIG_NET_VENDOR_CADENCE) += cadence/ obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/ diff --git a/drivers/net/ethernet/asix/Kconfig b/drivers/net/ethernet/asix/Kconfig new file mode 100644 index 000000000000..eed02453314c --- /dev/null +++ b/drivers/net/ethernet/asix/Kconfig @@ -0,0 +1,35 @@ +# +# Asix network device configuration +# + +config NET_VENDOR_ASIX + bool "Asix devices" + default y + help + If you have a network (Ethernet, non-USB, not NE2000 compatible) + interface based on a chip from ASIX, say Y. + +if NET_VENDOR_ASIX + +config SPI_AX88796C + tristate "Asix AX88796C-SPI support" + select PHYLIB + depends on SPI + depends on GPIOLIB + help + Say Y here if you intend to use ASIX AX88796C attached in SPI mode. + +config SPI_AX88796C_COMPRESSION + bool "SPI transfer compression" + default n + depends on SPI_AX88796C + help + Say Y here to enable SPI transfer compression. It saves up + to 24 dummy cycles during each transfer which may noticeably + speed up short transfers. This sets the default value that is + inherited by network interfaces during probe. It can be + changed at run time via spi-compression ethtool tunable. + + If unsure say N. + +endif # NET_VENDOR_ASIX diff --git a/drivers/net/ethernet/asix/Makefile b/drivers/net/ethernet/asix/Makefile new file mode 100644 index 000000000000..0bfbbb042634 --- /dev/null +++ b/drivers/net/ethernet/asix/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the Asix network device drivers. +# + +obj-$(CONFIG_SPI_AX88796C) += ax88796c.o +ax88796c-y := ax88796c_main.o ax88796c_ioctl.o ax88796c_spi.o diff --git a/drivers/net/ethernet/asix/ax88796c_ioctl.c b/drivers/net/ethernet/asix/ax88796c_ioctl.c new file mode 100644 index 000000000000..916ae380a004 --- /dev/null +++ b/drivers/net/ethernet/asix/ax88796c_ioctl.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2010 ASIX Electronics Corporation + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * ASIX AX88796C SPI Fast Ethernet Linux driver + */ + +#define pr_fmt(fmt) "ax88796c: " fmt + +#include +#include +#include +#include + +#include "ax88796c_main.h" +#include "ax88796c_ioctl.h" + +static const char ax88796c_priv_flag_names[][ETH_GSTRING_LEN] = { + "SPICompression", +}; + +static void +ax88796c_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) +{ + /* Inherit standard device info */ + strncpy(info->driver, DRV_NAME, sizeof(info->driver)); +} + +static u32 ax88796c_get_msglevel(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + + return ax_local->msg_enable; +} + +static void ax88796c_set_msglevel(struct net_device *ndev, u32 level) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + + ax_local->msg_enable = level; +} + +static void +ax88796c_get_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + + pause->tx_pause = !!(ax_local->flowctrl & AX_FC_TX); + pause->rx_pause = !!(ax_local->flowctrl & AX_FC_RX); + pause->autoneg = (ax_local->flowctrl & AX_FC_ANEG) ? + AUTONEG_ENABLE : + AUTONEG_DISABLE; +} + +static int +ax88796c_set_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + int fc; + + /* The following logic comes from phylink_ethtool_set_pauseparam() */ + fc = pause->tx_pause ? AX_FC_TX : 0; + fc |= pause->rx_pause ? AX_FC_RX : 0; + fc |= pause->autoneg ? AX_FC_ANEG : 0; + + ax_local->flowctrl = fc; + + if (pause->autoneg) { + phy_set_asym_pause(ax_local->phydev, pause->tx_pause, + pause->rx_pause); + } else { + int maccr = 0; + + phy_set_asym_pause(ax_local->phydev, 0, 0); + maccr |= (ax_local->flowctrl & AX_FC_RX) ? MACCR_RXFC_ENABLE : 0; + maccr |= (ax_local->flowctrl & AX_FC_TX) ? MACCR_TXFC_ENABLE : 0; + + mutex_lock(&ax_local->spi_lock); + + maccr |= AX_READ(&ax_local->ax_spi, P0_MACCR) & + ~(MACCR_TXFC_ENABLE | MACCR_RXFC_ENABLE); + AX_WRITE(&ax_local->ax_spi, maccr, P0_MACCR); + + mutex_unlock(&ax_local->spi_lock); + } + + return 0; +} + +static int ax88796c_get_regs_len(struct net_device *ndev) +{ + return AX88796C_REGDUMP_LEN + AX88796C_PHY_REGDUMP_LEN; +} + +static void +ax88796c_get_regs(struct net_device *ndev, struct ethtool_regs *regs, void *_p) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + int offset, i; + u16 *p = _p; + + memset(p, 0, ax88796c_get_regs_len(ndev)); + + mutex_lock(&ax_local->spi_lock); + + for (offset = 0; offset < AX88796C_REGDUMP_LEN; offset += 2) { + if (!test_bit(offset / 2, ax88796c_no_regs_mask)) + *p = AX_READ(&ax_local->ax_spi, offset); + p++; + } + + mutex_unlock(&ax_local->spi_lock); + + for (i = 0; i < AX88796C_PHY_REGDUMP_LEN / 2; i++) { + *p = phy_read(ax_local->phydev, i); + p++; + } +} + +static void +ax88796c_get_strings(struct net_device *ndev, u32 stringset, u8 *data) +{ + switch (stringset) { + case ETH_SS_PRIV_FLAGS: + memcpy(data, ax88796c_priv_flag_names, + sizeof(ax88796c_priv_flag_names)); + break; + } +} + +static int +ax88796c_get_sset_count(struct net_device *ndev, int stringset) +{ + int ret = 0; + + switch (stringset) { + case ETH_SS_PRIV_FLAGS: + ret = ARRAY_SIZE(ax88796c_priv_flag_names); + break; + default: + ret = -EOPNOTSUPP; + } + + return ret; +} + +static int ax88796c_set_priv_flags(struct net_device *ndev, u32 flags) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + + if (flags & ~AX_PRIV_FLAGS_MASK) + return -EOPNOTSUPP; + + if ((ax_local->priv_flags ^ flags) & AX_CAP_COMP) + if (netif_running(ndev)) + return -EBUSY; + + ax_local->priv_flags = flags; + + return 0; +} + +static u32 ax88796c_get_priv_flags(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + + return ax_local->priv_flags; +} + +int ax88796c_mdio_read(struct mii_bus *mdiobus, int phy_id, int loc) +{ + struct ax88796c_device *ax_local = mdiobus->priv; + int ret; + + mutex_lock(&ax_local->spi_lock); + AX_WRITE(&ax_local->ax_spi, MDIOCR_RADDR(loc) + | MDIOCR_FADDR(phy_id) | MDIOCR_READ, P2_MDIOCR); + + ret = read_poll_timeout(AX_READ, ret, + (ret != 0), + 0, jiffies_to_usecs(HZ / 100), false, + &ax_local->ax_spi, P2_MDIOCR); + if (!ret) + ret = AX_READ(&ax_local->ax_spi, P2_MDIODR); + + mutex_unlock(&ax_local->spi_lock); + + return ret; +} + +int +ax88796c_mdio_write(struct mii_bus *mdiobus, int phy_id, int loc, u16 val) +{ + struct ax88796c_device *ax_local = mdiobus->priv; + int ret; + + mutex_lock(&ax_local->spi_lock); + AX_WRITE(&ax_local->ax_spi, val, P2_MDIODR); + + AX_WRITE(&ax_local->ax_spi, + MDIOCR_RADDR(loc) | MDIOCR_FADDR(phy_id) + | MDIOCR_WRITE, P2_MDIOCR); + + ret = read_poll_timeout(AX_READ, ret, + ((ret & MDIOCR_VALID) != 0), 0, + jiffies_to_usecs(HZ / 100), false, + &ax_local->ax_spi, P2_MDIOCR); + mutex_unlock(&ax_local->spi_lock); + + return ret; +} + +const struct ethtool_ops ax88796c_ethtool_ops = { + .get_drvinfo = ax88796c_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_msglevel = ax88796c_get_msglevel, + .set_msglevel = ax88796c_set_msglevel, + .get_link_ksettings = phy_ethtool_get_link_ksettings, + .set_link_ksettings = phy_ethtool_set_link_ksettings, + .nway_reset = phy_ethtool_nway_reset, + .get_pauseparam = ax88796c_get_pauseparam, + .set_pauseparam = ax88796c_set_pauseparam, + .get_regs_len = ax88796c_get_regs_len, + .get_regs = ax88796c_get_regs, + .get_strings = ax88796c_get_strings, + .get_sset_count = ax88796c_get_sset_count, + .get_priv_flags = ax88796c_get_priv_flags, + .set_priv_flags = ax88796c_set_priv_flags, +}; + +int ax88796c_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) +{ + int ret; + + ret = phy_mii_ioctl(ndev->phydev, ifr, cmd); + + return ret; +} diff --git a/drivers/net/ethernet/asix/ax88796c_ioctl.h b/drivers/net/ethernet/asix/ax88796c_ioctl.h new file mode 100644 index 000000000000..34d2a7dcc5ef --- /dev/null +++ b/drivers/net/ethernet/asix/ax88796c_ioctl.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2010 ASIX Electronics Corporation + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * ASIX AX88796C SPI Fast Ethernet Linux driver + */ + +#ifndef _AX88796C_IOCTL_H +#define _AX88796C_IOCTL_H + +#include +#include + +#include "ax88796c_main.h" + +extern const struct ethtool_ops ax88796c_ethtool_ops; + +bool ax88796c_check_power(const struct ax88796c_device *ax_local); +bool ax88796c_check_power_and_wake(struct ax88796c_device *ax_local); +void ax88796c_set_power_saving(struct ax88796c_device *ax_local, u8 ps_level); +int ax88796c_mdio_read(struct mii_bus *mdiobus, int phy_id, int loc); +int ax88796c_mdio_write(struct mii_bus *mdiobus, int phy_id, int loc, u16 val); +int ax88796c_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); + +#endif diff --git a/drivers/net/ethernet/asix/ax88796c_main.c b/drivers/net/ethernet/asix/ax88796c_main.c new file mode 100644 index 000000000000..4dca2e760105 --- /dev/null +++ b/drivers/net/ethernet/asix/ax88796c_main.c @@ -0,0 +1,1146 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2010 ASIX Electronics Corporation + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * ASIX AX88796C SPI Fast Ethernet Linux driver + */ + +#define pr_fmt(fmt) "ax88796c: " fmt + +#include "ax88796c_main.h" +#include "ax88796c_ioctl.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int comp = IS_ENABLED(CONFIG_SPI_AX88796C_COMPRESSION); +static int msg_enable = NETIF_MSG_PROBE | + NETIF_MSG_LINK | + NETIF_MSG_RX_ERR | + NETIF_MSG_TX_ERR; + +static char *no_regs_list = "80018001,e1918001,8001a001,fc0d0000"; +unsigned long ax88796c_no_regs_mask[AX88796C_REGDUMP_LEN / (sizeof(unsigned long) * 8)]; + +module_param(msg_enable, int, 0444); +MODULE_PARM_DESC(msg_enable, "Message mask (see linux/netdevice.h for bitmap)"); + +static int ax88796c_soft_reset(struct ax88796c_device *ax_local) +{ + u16 temp; + int ret; + + lockdep_assert_held(&ax_local->spi_lock); + + AX_WRITE(&ax_local->ax_spi, PSR_RESET, P0_PSR); + AX_WRITE(&ax_local->ax_spi, PSR_RESET_CLR, P0_PSR); + + ret = read_poll_timeout(AX_READ, ret, + (ret & PSR_DEV_READY), + 0, jiffies_to_usecs(160 * HZ / 1000), false, + &ax_local->ax_spi, P0_PSR); + if (ret) + return ret; + + temp = AX_READ(&ax_local->ax_spi, P4_SPICR); + if (ax_local->priv_flags & AX_CAP_COMP) { + AX_WRITE(&ax_local->ax_spi, + (temp | SPICR_RCEN | SPICR_QCEN), P4_SPICR); + ax_local->ax_spi.comp = 1; + } else { + AX_WRITE(&ax_local->ax_spi, + (temp & ~(SPICR_RCEN | SPICR_QCEN)), P4_SPICR); + ax_local->ax_spi.comp = 0; + } + + return 0; +} + +static int ax88796c_reload_eeprom(struct ax88796c_device *ax_local) +{ + int ret; + + lockdep_assert_held(&ax_local->spi_lock); + + AX_WRITE(&ax_local->ax_spi, EECR_RELOAD, P3_EECR); + + ret = read_poll_timeout(AX_READ, ret, + (ret & PSR_DEV_READY), + 0, jiffies_to_usecs(2 * HZ / 1000), false, + &ax_local->ax_spi, P0_PSR); + if (ret) { + dev_err(&ax_local->spi->dev, + "timeout waiting for reload eeprom\n"); + return ret; + } + + return 0; +} + +static void ax88796c_set_hw_multicast(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + int mc_count = netdev_mc_count(ndev); + u16 rx_ctl = RXCR_AB; + + lockdep_assert_held(&ax_local->spi_lock); + + memset(ax_local->multi_filter, 0, AX_MCAST_FILTER_SIZE); + + if (ndev->flags & IFF_PROMISC) { + rx_ctl |= RXCR_PRO; + + } else if (ndev->flags & IFF_ALLMULTI || mc_count > AX_MAX_MCAST) { + rx_ctl |= RXCR_AMALL; + + } else if (mc_count == 0) { + /* just broadcast and directed */ + } else { + u32 crc_bits; + int i; + struct netdev_hw_addr *ha; + + netdev_for_each_mc_addr(ha, ndev) { + crc_bits = ether_crc(ETH_ALEN, ha->addr); + ax_local->multi_filter[crc_bits >> 29] |= + (1 << ((crc_bits >> 26) & 7)); + } + + for (i = 0; i < 4; i++) { + AX_WRITE(&ax_local->ax_spi, + ((ax_local->multi_filter[i * 2 + 1] << 8) | + ax_local->multi_filter[i * 2]), P3_MFAR(i)); + } + } + + AX_WRITE(&ax_local->ax_spi, rx_ctl, P2_RXCR); +} + +static void ax88796c_set_mac_addr(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + + lockdep_assert_held(&ax_local->spi_lock); + + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[4] << 8) | + (u16)ndev->dev_addr[5]), P3_MACASR0); + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[2] << 8) | + (u16)ndev->dev_addr[3]), P3_MACASR1); + AX_WRITE(&ax_local->ax_spi, ((u16)(ndev->dev_addr[0] << 8) | + (u16)ndev->dev_addr[1]), P3_MACASR2); +} + +static void ax88796c_load_mac_addr(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + u16 temp; + + lockdep_assert_held(&ax_local->spi_lock); + + /* Try the device tree first */ + if (!eth_platform_get_mac_address(&ax_local->spi->dev, ndev->dev_addr) && + is_valid_ether_addr(ndev->dev_addr)) { + if (netif_msg_probe(ax_local)) + dev_info(&ax_local->spi->dev, + "MAC address read from device tree\n"); + return; + } + + /* Read the MAC address from AX88796C */ + temp = AX_READ(&ax_local->ax_spi, P3_MACASR0); + ndev->dev_addr[5] = (u8)temp; + ndev->dev_addr[4] = (u8)(temp >> 8); + + temp = AX_READ(&ax_local->ax_spi, P3_MACASR1); + ndev->dev_addr[3] = (u8)temp; + ndev->dev_addr[2] = (u8)(temp >> 8); + + temp = AX_READ(&ax_local->ax_spi, P3_MACASR2); + ndev->dev_addr[1] = (u8)temp; + ndev->dev_addr[0] = (u8)(temp >> 8); + + if (is_valid_ether_addr(ndev->dev_addr)) { + if (netif_msg_probe(ax_local)) + dev_info(&ax_local->spi->dev, + "MAC address read from ASIX chip\n"); + return; + } + + /* Use random address if none found */ + if (netif_msg_probe(ax_local)) + dev_info(&ax_local->spi->dev, "Use random MAC address\n"); + eth_hw_addr_random(ndev); +} + +static void ax88796c_proc_tx_hdr(struct tx_pkt_info *info, u8 ip_summed) +{ + u16 pkt_len_bar = (~info->pkt_len & TX_HDR_SOP_PKTLENBAR); + + /* Prepare SOP header */ + info->sop.flags_len = info->pkt_len | + ((ip_summed == CHECKSUM_NONE) || + (ip_summed == CHECKSUM_UNNECESSARY) ? TX_HDR_SOP_DICF : 0); + + info->sop.seq_lenbar = ((info->seq_num << 11) & TX_HDR_SOP_SEQNUM) + | pkt_len_bar; + cpu_to_be16s(&info->sop.flags_len); + cpu_to_be16s(&info->sop.seq_lenbar); + + /* Prepare Segment header */ + info->seg.flags_seqnum_seglen = TX_HDR_SEG_FS | TX_HDR_SEG_LS + | info->pkt_len; + + info->seg.eo_so_seglenbar = pkt_len_bar; + + cpu_to_be16s(&info->seg.flags_seqnum_seglen); + cpu_to_be16s(&info->seg.eo_so_seglenbar); + + /* Prepare EOP header */ + info->eop.seq_len = ((info->seq_num << 11) & + TX_HDR_EOP_SEQNUM) | info->pkt_len; + info->eop.seqbar_lenbar = ((~info->seq_num << 11) & + TX_HDR_EOP_SEQNUMBAR) | pkt_len_bar; + + cpu_to_be16s(&info->eop.seq_len); + cpu_to_be16s(&info->eop.seqbar_lenbar); +} + +static int +ax88796c_check_free_pages(struct ax88796c_device *ax_local, u8 need_pages) +{ + u8 free_pages; + u16 tmp; + + lockdep_assert_held(&ax_local->spi_lock); + + free_pages = AX_READ(&ax_local->ax_spi, P0_TFBFCR) & TX_FREEBUF_MASK; + if (free_pages < need_pages) { + /* schedule free page interrupt */ + tmp = AX_READ(&ax_local->ax_spi, P0_TFBFCR) + & TFBFCR_SCHE_FREE_PAGE; + AX_WRITE(&ax_local->ax_spi, tmp | TFBFCR_TX_PAGE_SET | + TFBFCR_SET_FREE_PAGE(need_pages), + P0_TFBFCR); + return -ENOMEM; + } + + return 0; +} + +static struct sk_buff * +ax88796c_tx_fixup(struct net_device *ndev, struct sk_buff_head *q) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + u8 spi_len = ax_local->ax_spi.comp ? 1 : 4; + struct sk_buff *skb; + struct tx_pkt_info info; + struct skb_data *entry; + u16 pkt_len; + u8 padlen, seq_num; + u8 need_pages; + int headroom; + int tailroom; + + if (skb_queue_empty(q)) + return NULL; + + skb = skb_peek(q); + pkt_len = skb->len; + need_pages = (pkt_len + TX_OVERHEAD + 127) >> 7; + if (ax88796c_check_free_pages(ax_local, need_pages) != 0) + return NULL; + + headroom = skb_headroom(skb); + tailroom = skb_tailroom(skb); + padlen = round_up(pkt_len, 4) - pkt_len; + seq_num = ++ax_local->seq_num & 0x1F; + + info.pkt_len = pkt_len; + + if (skb_cloned(skb) || + (headroom < (TX_OVERHEAD + spi_len)) || + (tailroom < (padlen + TX_EOP_SIZE))) { + size_t h = max((TX_OVERHEAD + spi_len) - headroom, 0); + size_t t = max((padlen + TX_EOP_SIZE) - tailroom, 0); + + if (pskb_expand_head(skb, h, t, GFP_KERNEL)) + return NULL; + } + + info.seq_num = seq_num; + ax88796c_proc_tx_hdr(&info, skb->ip_summed); + + /* SOP and SEG header */ + memcpy(skb_push(skb, TX_OVERHEAD), &info.sop, TX_OVERHEAD); + + /* Write SPI TXQ header */ + memcpy(skb_push(skb, spi_len), ax88796c_tx_cmd_buf, spi_len); + + /* Make 32-bit alignment */ + skb_put(skb, padlen); + + /* EOP header */ + memcpy(skb_put(skb, TX_EOP_SIZE), &info.eop, TX_EOP_SIZE); + + skb_unlink(skb, q); + + entry = (struct skb_data *)skb->cb; + memset(entry, 0, sizeof(*entry)); + entry->len = pkt_len; + + if (netif_msg_pktdata(ax_local)) { + char pfx[IFNAMSIZ + 7]; + + snprintf(pfx, sizeof(pfx), "%s: ", ndev->name); + + netdev_info(ndev, "TX packet len %d, total len %d, seq %d\n", + pkt_len, skb->len, seq_num); + + netdev_info(ndev, " SPI Header:\n"); + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, + skb->data, 4, 0); + + netdev_info(ndev, " TX SOP:\n"); + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, + skb->data + 4, TX_OVERHEAD, 0); + + netdev_info(ndev, " TX packet:\n"); + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, + skb->data + 4 + TX_OVERHEAD, + skb->len - TX_EOP_SIZE - 4 - TX_OVERHEAD, 0); + + netdev_info(ndev, " TX EOP:\n"); + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, + skb->data + skb->len - 4, 4, 0); + } + + return skb; +} + +static int ax88796c_hard_xmit(struct ax88796c_device *ax_local) +{ + struct ax88796c_pcpu_stats *stats; + struct sk_buff *tx_skb; + struct skb_data *entry; + + lockdep_assert_held(&ax_local->spi_lock); + + stats = this_cpu_ptr(ax_local->stats); + tx_skb = ax88796c_tx_fixup(ax_local->ndev, &ax_local->tx_wait_q); + + if (!tx_skb) { + this_cpu_inc(ax_local->stats->tx_dropped); + return 0; + } + entry = (struct skb_data *)tx_skb->cb; + + AX_WRITE(&ax_local->ax_spi, + (TSNR_TXB_START | TSNR_PKT_CNT(1)), P0_TSNR); + + axspi_write_txq(&ax_local->ax_spi, tx_skb->data, tx_skb->len); + + if (((AX_READ(&ax_local->ax_spi, P0_TSNR) & TXNR_TXB_IDLE) == 0) || + ((ISR_TXERR & AX_READ(&ax_local->ax_spi, P0_ISR)) != 0)) { + /* Ack tx error int */ + AX_WRITE(&ax_local->ax_spi, ISR_TXERR, P0_ISR); + + this_cpu_inc(ax_local->stats->tx_dropped); + + if (net_ratelimit()) + netif_err(ax_local, tx_err, ax_local->ndev, + "TX FIFO error, re-initialize the TX bridge\n"); + + /* Reinitial tx bridge */ + AX_WRITE(&ax_local->ax_spi, TXNR_TXB_REINIT | + AX_READ(&ax_local->ax_spi, P0_TSNR), P0_TSNR); + ax_local->seq_num = 0; + } else { + u64_stats_update_begin(&stats->syncp); + u64_stats_inc(&stats->tx_packets); + u64_stats_add(&stats->tx_bytes, entry->len); + u64_stats_update_end(&stats->syncp); + } + + entry->state = tx_done; + dev_kfree_skb(tx_skb); + + return 1; +} + +static int +ax88796c_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + + skb_queue_tail(&ax_local->tx_wait_q, skb); + if (skb_queue_len(&ax_local->tx_wait_q) > TX_QUEUE_HIGH_WATER) + netif_stop_queue(ndev); + + set_bit(EVENT_TX, &ax_local->flags); + schedule_work(&ax_local->ax_work); + + return NETDEV_TX_OK; +} + +static void +ax88796c_skb_return(struct ax88796c_device *ax_local, + struct sk_buff *skb, struct rx_header *rxhdr) +{ + struct net_device *ndev = ax_local->ndev; + struct ax88796c_pcpu_stats *stats; + int status; + + stats = this_cpu_ptr(ax_local->stats); + + do { + if (!(ndev->features & NETIF_F_RXCSUM)) + break; + + /* checksum error bit is set */ + if ((rxhdr->flags & RX_HDR3_L3_ERR) || + (rxhdr->flags & RX_HDR3_L4_ERR)) + break; + + /* Other types may be indicated by more than one bit. */ + if ((rxhdr->flags & RX_HDR3_L4_TYPE_TCP) || + (rxhdr->flags & RX_HDR3_L4_TYPE_UDP)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + } while (0); + + u64_stats_update_begin(&stats->syncp); + u64_stats_inc(&stats->rx_packets); + u64_stats_add(&stats->rx_bytes, skb->len); + u64_stats_update_end(&stats->syncp); + + skb->dev = ndev; + skb->protocol = eth_type_trans(skb, ax_local->ndev); + + netif_info(ax_local, rx_status, ndev, "< rx, len %zu, type 0x%x\n", + skb->len + sizeof(struct ethhdr), skb->protocol); + + status = netif_rx_ni(skb); + if (status != NET_RX_SUCCESS && net_ratelimit()) + netif_info(ax_local, rx_err, ndev, + "netif_rx status %d\n", status); +} + +static void +ax88796c_rx_fixup(struct ax88796c_device *ax_local, struct sk_buff *rx_skb) +{ + struct rx_header *rxhdr = (struct rx_header *)rx_skb->data; + struct net_device *ndev = ax_local->ndev; + u16 len; + + be16_to_cpus(&rxhdr->flags_len); + be16_to_cpus(&rxhdr->seq_lenbar); + be16_to_cpus(&rxhdr->flags); + + if ((rxhdr->flags_len & RX_HDR1_PKT_LEN) != + (~rxhdr->seq_lenbar & 0x7FF)) { + netif_err(ax_local, rx_err, ndev, "Header error\n"); + + this_cpu_inc(ax_local->stats->rx_frame_errors); + kfree_skb(rx_skb); + return; + } + + if ((rxhdr->flags_len & RX_HDR1_MII_ERR) || + (rxhdr->flags_len & RX_HDR1_CRC_ERR)) { + netif_err(ax_local, rx_err, ndev, "CRC or MII error\n"); + + this_cpu_inc(ax_local->stats->rx_crc_errors); + kfree_skb(rx_skb); + return; + } + + len = rxhdr->flags_len & RX_HDR1_PKT_LEN; + if (netif_msg_pktdata(ax_local)) { + char pfx[IFNAMSIZ + 7]; + + snprintf(pfx, sizeof(pfx), "%s: ", ndev->name); + netdev_info(ndev, "RX data, total len %d, packet len %d\n", + rx_skb->len, len); + + netdev_info(ndev, " Dump RX packet header:"); + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, + rx_skb->data, sizeof(*rxhdr), 0); + + netdev_info(ndev, " Dump RX packet:"); + print_hex_dump(KERN_INFO, pfx, DUMP_PREFIX_OFFSET, 16, 1, + rx_skb->data + sizeof(*rxhdr), len, 0); + } + + skb_pull(rx_skb, sizeof(*rxhdr)); + pskb_trim(rx_skb, len); + + ax88796c_skb_return(ax_local, rx_skb, rxhdr); +} + +static int ax88796c_receive(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + struct skb_data *entry; + u16 w_count, pkt_len; + struct sk_buff *skb; + u8 pkt_cnt; + + lockdep_assert_held(&ax_local->spi_lock); + + /* check rx packet and total word count */ + AX_WRITE(&ax_local->ax_spi, AX_READ(&ax_local->ax_spi, P0_RTWCR) + | RTWCR_RX_LATCH, P0_RTWCR); + + pkt_cnt = AX_READ(&ax_local->ax_spi, P0_RXBCR2) & RXBCR2_PKT_MASK; + if (!pkt_cnt) + return 0; + + pkt_len = AX_READ(&ax_local->ax_spi, P0_RCPHR) & 0x7FF; + + w_count = round_up(pkt_len + 6, 4) >> 1; + + skb = netdev_alloc_skb(ndev, w_count * 2); + if (!skb) { + AX_WRITE(&ax_local->ax_spi, RXBCR1_RXB_DISCARD, P0_RXBCR1); + this_cpu_inc(ax_local->stats->rx_dropped); + return 0; + } + entry = (struct skb_data *)skb->cb; + + AX_WRITE(&ax_local->ax_spi, RXBCR1_RXB_START | w_count, P0_RXBCR1); + + axspi_read_rxq(&ax_local->ax_spi, + skb_put(skb, w_count * 2), skb->len); + + /* Check if rx bridge is idle */ + if ((AX_READ(&ax_local->ax_spi, P0_RXBCR2) & RXBCR2_RXB_IDLE) == 0) { + if (net_ratelimit()) + netif_err(ax_local, rx_err, ndev, + "Rx Bridge is not idle\n"); + AX_WRITE(&ax_local->ax_spi, RXBCR2_RXB_REINIT, P0_RXBCR2); + + entry->state = rx_err; + } else { + entry->state = rx_done; + } + + AX_WRITE(&ax_local->ax_spi, ISR_RXPKT, P0_ISR); + + ax88796c_rx_fixup(ax_local, skb); + + return 1; +} + +static int ax88796c_process_isr(struct ax88796c_device *ax_local) +{ + struct net_device *ndev = ax_local->ndev; + int todo = 0; + u16 isr; + + lockdep_assert_held(&ax_local->spi_lock); + + isr = AX_READ(&ax_local->ax_spi, P0_ISR); + AX_WRITE(&ax_local->ax_spi, isr, P0_ISR); + + netif_dbg(ax_local, intr, ndev, " ISR 0x%04x\n", isr); + + if (isr & ISR_TXERR) { + netif_dbg(ax_local, intr, ndev, " TXERR interrupt\n"); + AX_WRITE(&ax_local->ax_spi, TXNR_TXB_REINIT, P0_TSNR); + ax_local->seq_num = 0x1f; + } + + if (isr & ISR_TXPAGES) { + netif_dbg(ax_local, intr, ndev, " TXPAGES interrupt\n"); + set_bit(EVENT_TX, &ax_local->flags); + } + + if (isr & ISR_LINK) { + netif_dbg(ax_local, intr, ndev, " Link change interrupt\n"); + phy_mac_interrupt(ax_local->ndev->phydev); + } + + if (isr & ISR_RXPKT) { + netif_dbg(ax_local, intr, ndev, " RX interrupt\n"); + todo = ax88796c_receive(ax_local->ndev); + } + + return todo; +} + +static irqreturn_t ax88796c_interrupt(int irq, void *dev_instance) +{ + struct ax88796c_device *ax_local; + struct net_device *ndev; + + ndev = dev_instance; + if (!ndev) { + pr_err("irq %d for unknown device.\n", irq); + return IRQ_RETVAL(0); + } + ax_local = to_ax88796c_device(ndev); + + disable_irq_nosync(irq); + + netif_dbg(ax_local, intr, ndev, "Interrupt occurred\n"); + + set_bit(EVENT_INTR, &ax_local->flags); + schedule_work(&ax_local->ax_work); + + return IRQ_HANDLED; +} + +static void ax88796c_work(struct work_struct *work) +{ + struct ax88796c_device *ax_local = + container_of(work, struct ax88796c_device, ax_work); + + mutex_lock(&ax_local->spi_lock); + + if (test_bit(EVENT_SET_MULTI, &ax_local->flags)) { + ax88796c_set_hw_multicast(ax_local->ndev); + clear_bit(EVENT_SET_MULTI, &ax_local->flags); + } + + if (test_bit(EVENT_INTR, &ax_local->flags)) { + AX_WRITE(&ax_local->ax_spi, IMR_MASKALL, P0_IMR); + + while (ax88796c_process_isr(ax_local)) + /* nothing */; + + clear_bit(EVENT_INTR, &ax_local->flags); + + AX_WRITE(&ax_local->ax_spi, IMR_DEFAULT, P0_IMR); + + enable_irq(ax_local->ndev->irq); + } + + if (test_bit(EVENT_TX, &ax_local->flags)) { + while (skb_queue_len(&ax_local->tx_wait_q)) { + if (!ax88796c_hard_xmit(ax_local)) + break; + } + + clear_bit(EVENT_TX, &ax_local->flags); + + if (netif_queue_stopped(ax_local->ndev) && + (skb_queue_len(&ax_local->tx_wait_q) < TX_QUEUE_LOW_WATER)) + netif_wake_queue(ax_local->ndev); + } + + mutex_unlock(&ax_local->spi_lock); +} + +static void ax88796c_get_stats64(struct net_device *ndev, + struct rtnl_link_stats64 *stats) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + u32 rx_frame_errors = 0, rx_crc_errors = 0; + u32 rx_dropped = 0, tx_dropped = 0; + unsigned int start; + int cpu; + + for_each_possible_cpu(cpu) { + struct ax88796c_pcpu_stats *s; + u64 rx_packets, rx_bytes; + u64 tx_packets, tx_bytes; + + s = per_cpu_ptr(ax_local->stats, cpu); + + do { + start = u64_stats_fetch_begin_irq(&s->syncp); + rx_packets = u64_stats_read(&s->rx_packets); + rx_bytes = u64_stats_read(&s->rx_bytes); + tx_packets = u64_stats_read(&s->tx_packets); + tx_bytes = u64_stats_read(&s->tx_bytes); + } while (u64_stats_fetch_retry_irq(&s->syncp, start)); + + stats->rx_packets += rx_packets; + stats->rx_bytes += rx_bytes; + stats->tx_packets += tx_packets; + stats->tx_bytes += tx_bytes; + + rx_dropped += stats->rx_dropped; + tx_dropped += stats->tx_dropped; + rx_frame_errors += stats->rx_frame_errors; + rx_crc_errors += stats->rx_crc_errors; + } + + stats->rx_dropped = rx_dropped; + stats->tx_dropped = tx_dropped; + stats->rx_frame_errors = rx_frame_errors; + stats->rx_crc_errors = rx_crc_errors; +} + +static void ax88796c_set_mac(struct ax88796c_device *ax_local) +{ + u16 maccr; + + maccr = (ax_local->link) ? MACCR_RXEN : 0; + + switch (ax_local->speed) { + case SPEED_100: + maccr |= MACCR_SPEED_100; + case SPEED_10: + case SPEED_UNKNOWN: + break; + default: + return; + } + + switch (ax_local->duplex) { + case DUPLEX_FULL: + maccr |= MACCR_SPEED_100; + case DUPLEX_HALF: + case DUPLEX_UNKNOWN: + break; + default: + return; + } + + if (ax_local->flowctrl & AX_FC_ANEG && + ax_local->phydev->autoneg) { + maccr |= ax_local->pause ? MACCR_RXFC_ENABLE : 0; + maccr |= !ax_local->pause != !ax_local->asym_pause ? + MACCR_TXFC_ENABLE : 0; + } else { + maccr |= (ax_local->flowctrl & AX_FC_RX) ? MACCR_RXFC_ENABLE : 0; + maccr |= (ax_local->flowctrl & AX_FC_TX) ? MACCR_TXFC_ENABLE : 0; + } + + mutex_lock(&ax_local->spi_lock); + + maccr |= AX_READ(&ax_local->ax_spi, P0_MACCR) & + ~(MACCR_DUPLEX_FULL | MACCR_SPEED_100 | + MACCR_TXFC_ENABLE | MACCR_RXFC_ENABLE); + AX_WRITE(&ax_local->ax_spi, maccr, P0_MACCR); + + mutex_unlock(&ax_local->spi_lock); +} + +static void ax88796c_handle_link_change(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + struct phy_device *phydev = ndev->phydev; + bool update = false; + + if (phydev->link && (ax_local->speed != phydev->speed || + ax_local->duplex != phydev->duplex || + ax_local->pause != phydev->pause || + ax_local->asym_pause != phydev->asym_pause)) { + ax_local->speed = phydev->speed; + ax_local->duplex = phydev->duplex; + ax_local->pause = phydev->pause; + ax_local->asym_pause = phydev->asym_pause; + update = true; + } + + if (phydev->link != ax_local->link) { + if (!phydev->link) { + ax_local->speed = SPEED_UNKNOWN; + ax_local->duplex = DUPLEX_UNKNOWN; + } + + ax_local->link = phydev->link; + update = true; + } + + if (update) + ax88796c_set_mac(ax_local); + + if (net_ratelimit()) + phy_print_status(ndev->phydev); +} + +static void ax88796c_set_csums(struct ax88796c_device *ax_local) +{ + struct net_device *ndev = ax_local->ndev; + + lockdep_assert_held(&ax_local->spi_lock); + + if (ndev->features & NETIF_F_RXCSUM) { + AX_WRITE(&ax_local->ax_spi, COERCR0_DEFAULT, P4_COERCR0); + AX_WRITE(&ax_local->ax_spi, COERCR1_DEFAULT, P4_COERCR1); + } else { + AX_WRITE(&ax_local->ax_spi, 0, P4_COERCR0); + AX_WRITE(&ax_local->ax_spi, 0, P4_COERCR1); + } + + if (ndev->features & NETIF_F_HW_CSUM) { + AX_WRITE(&ax_local->ax_spi, COETCR0_DEFAULT, P4_COETCR0); + AX_WRITE(&ax_local->ax_spi, COETCR1_TXPPPE, P4_COETCR1); + } else { + AX_WRITE(&ax_local->ax_spi, 0, P4_COETCR0); + AX_WRITE(&ax_local->ax_spi, 0, P4_COETCR1); + } +} + +static int +ax88796c_open(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + unsigned long irq_flag = 0; + int fc = AX_FC_NONE; + int ret; + u16 t; + + ret = request_irq(ndev->irq, ax88796c_interrupt, + irq_flag, ndev->name, ndev); + if (ret) { + netdev_err(ndev, "unable to get IRQ %d (errno=%d).\n", + ndev->irq, ret); + return ret; + } + + mutex_lock(&ax_local->spi_lock); + + ret = ax88796c_soft_reset(ax_local); + if (ret < 0) { + free_irq(ndev->irq, ndev); + mutex_unlock(&ax_local->spi_lock); + return ret; + } + ax_local->seq_num = 0x1f; + + ax88796c_set_mac_addr(ndev); + ax88796c_set_csums(ax_local); + + /* Disable stuffing packet */ + t = AX_READ(&ax_local->ax_spi, P1_RXBSPCR); + t &= ~RXBSPCR_STUF_ENABLE; + AX_WRITE(&ax_local->ax_spi, t, P1_RXBSPCR); + + /* Enable RX packet process */ + AX_WRITE(&ax_local->ax_spi, RPPER_RXEN, P1_RPPER); + + t = AX_READ(&ax_local->ax_spi, P0_FER); + t |= FER_RXEN | FER_TXEN | FER_BSWAP | FER_IRQ_PULL; + AX_WRITE(&ax_local->ax_spi, t, P0_FER); + + /* Setup LED mode */ + AX_WRITE(&ax_local->ax_spi, + (LCR_LED0_EN | LCR_LED0_DUPLEX | LCR_LED1_EN | + LCR_LED1_100MODE), P2_LCR0); + AX_WRITE(&ax_local->ax_spi, + (AX_READ(&ax_local->ax_spi, P2_LCR1) & LCR_LED2_MASK) | + LCR_LED2_EN | LCR_LED2_LINK, P2_LCR1); + + /* Disable PHY auto-polling */ + AX_WRITE(&ax_local->ax_spi, PCR_PHYID(AX88796C_PHY_ID), P2_PCR); + + /* Enable MAC interrupts */ + AX_WRITE(&ax_local->ax_spi, IMR_DEFAULT, P0_IMR); + + mutex_unlock(&ax_local->spi_lock); + + /* Setup flow-control configuration */ + phy_support_asym_pause(ax_local->phydev); + + if (ax_local->phydev->advertising && + (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, + ax_local->phydev->advertising) || + linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, + ax_local->phydev->advertising))) + fc |= AX_FC_ANEG; + + fc |= linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, + ax_local->phydev->advertising) ? AX_FC_RX : 0; + fc |= (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, + ax_local->phydev->advertising) != + linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, + ax_local->phydev->advertising)) ? AX_FC_TX : 0; + ax_local->flowctrl = fc; + + phy_start(ax_local->ndev->phydev); + + netif_start_queue(ndev); + + spi_message_init(&ax_local->ax_spi.rx_msg); + + return 0; +} + +static int +ax88796c_close(struct net_device *ndev) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + + netif_stop_queue(ndev); + phy_stop(ndev->phydev); + + mutex_lock(&ax_local->spi_lock); + + /* Disable MAC interrupts */ + AX_WRITE(&ax_local->ax_spi, IMR_MASKALL, P0_IMR); + __skb_queue_purge(&ax_local->tx_wait_q); + ax88796c_soft_reset(ax_local); + + mutex_unlock(&ax_local->spi_lock); + + free_irq(ndev->irq, ndev); + + return 0; +} + +static int +ax88796c_set_features(struct net_device *ndev, netdev_features_t features) +{ + struct ax88796c_device *ax_local = to_ax88796c_device(ndev); + netdev_features_t changed = features ^ ndev->features; + + if (!(changed & (NETIF_F_RXCSUM | NETIF_F_HW_CSUM))) + return 0; + + ndev->features = features; + + if (changed & (NETIF_F_RXCSUM | NETIF_F_HW_CSUM)) + ax88796c_set_csums(ax_local); + + return 0; +} + +static const struct net_device_ops ax88796c_netdev_ops = { + .ndo_open = ax88796c_open, + .ndo_stop = ax88796c_close, + .ndo_start_xmit = ax88796c_start_xmit, + .ndo_get_stats64 = ax88796c_get_stats64, + .ndo_do_ioctl = ax88796c_ioctl, + .ndo_set_mac_address = eth_mac_addr, + .ndo_set_features = ax88796c_set_features, +}; + +static int ax88796c_hard_reset(struct ax88796c_device *ax_local) +{ + struct device *dev = (struct device *)&ax_local->spi->dev; + struct gpio_desc *reset_gpio; + + /* reset info */ + reset_gpio = gpiod_get(dev, "reset", 0); + if (IS_ERR(reset_gpio)) { + dev_err(dev, "Could not get 'reset' GPIO: %ld", PTR_ERR(reset_gpio)); + return PTR_ERR(reset_gpio); + } + + /* set reset */ + gpiod_direction_output(reset_gpio, 1); + msleep(100); + gpiod_direction_output(reset_gpio, 0); + gpiod_put(reset_gpio); + msleep(20); + + return 0; +} + +static int ax88796c_probe(struct spi_device *spi) +{ + char phy_id[MII_BUS_ID_SIZE + 3]; + struct ax88796c_device *ax_local; + struct net_device *ndev; + u16 temp; + int ret; + + ndev = devm_alloc_etherdev(&spi->dev, sizeof(*ax_local)); + if (!ndev) + return -ENOMEM; + + SET_NETDEV_DEV(ndev, &spi->dev); + + ax_local = to_ax88796c_device(ndev); + + dev_set_drvdata(&spi->dev, ax_local); + ax_local->spi = spi; + ax_local->ax_spi.spi = spi; + + ax_local->stats = + devm_netdev_alloc_pcpu_stats(&spi->dev, + struct ax88796c_pcpu_stats); + if (!ax_local->stats) + return -ENOMEM; + + ax_local->ndev = ndev; + ax_local->priv_flags |= comp ? AX_CAP_COMP : 0; + ax_local->msg_enable = msg_enable; + mutex_init(&ax_local->spi_lock); + + ax_local->mdiobus = devm_mdiobus_alloc(&spi->dev); + if (!ax_local->mdiobus) + return -ENOMEM; + + ax_local->mdiobus->priv = ax_local; + ax_local->mdiobus->read = ax88796c_mdio_read; + ax_local->mdiobus->write = ax88796c_mdio_write; + ax_local->mdiobus->name = "ax88976c-mdiobus"; + ax_local->mdiobus->phy_mask = (u32)~BIT(AX88796C_PHY_ID); + ax_local->mdiobus->parent = &spi->dev; + + snprintf(ax_local->mdiobus->id, MII_BUS_ID_SIZE, + "ax88796c-%s.%u", dev_name(&spi->dev), spi->chip_select); + + ret = devm_mdiobus_register(&spi->dev, ax_local->mdiobus); + if (ret < 0) { + dev_err(&spi->dev, "Could not register MDIO bus\n"); + return ret; + } + + if (netif_msg_probe(ax_local)) { + dev_info(&spi->dev, "AX88796C-SPI Configuration:\n"); + dev_info(&spi->dev, " Compression : %s\n", + ax_local->priv_flags & AX_CAP_COMP ? "ON" : "OFF"); + } + + ndev->irq = spi->irq; + ndev->netdev_ops = &ax88796c_netdev_ops; + ndev->ethtool_ops = &ax88796c_ethtool_ops; + ndev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + ndev->features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + ndev->needed_headroom = TX_OVERHEAD; + ndev->needed_tailroom = TX_EOP_SIZE; + + mutex_lock(&ax_local->spi_lock); + + /* ax88796c gpio reset */ + ax88796c_hard_reset(ax_local); + + /* Reset AX88796C */ + ret = ax88796c_soft_reset(ax_local); + if (ret < 0) { + ret = -ENODEV; + mutex_unlock(&ax_local->spi_lock); + goto err; + } + /* Check board revision */ + temp = AX_READ(&ax_local->ax_spi, P2_CRIR); + if ((temp & 0xF) != 0x0) { + dev_err(&spi->dev, "spi read failed: %d\n", temp); + ret = -ENODEV; + mutex_unlock(&ax_local->spi_lock); + goto err; + } + + /*Reload EEPROM*/ + ax88796c_reload_eeprom(ax_local); + + ax88796c_load_mac_addr(ndev); + + if (netif_msg_probe(ax_local)) + dev_info(&spi->dev, + "irq %d, MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", + ndev->irq, + ndev->dev_addr[0], ndev->dev_addr[1], + ndev->dev_addr[2], ndev->dev_addr[3], + ndev->dev_addr[4], ndev->dev_addr[5]); + + /* Disable power saving */ + AX_WRITE(&ax_local->ax_spi, (AX_READ(&ax_local->ax_spi, P0_PSCR) + & PSCR_PS_MASK) | PSCR_PS_D0, P0_PSCR); + + mutex_unlock(&ax_local->spi_lock); + + INIT_WORK(&ax_local->ax_work, ax88796c_work); + + skb_queue_head_init(&ax_local->tx_wait_q); + + snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, + ax_local->mdiobus->id, AX88796C_PHY_ID); + ax_local->phydev = phy_connect(ax_local->ndev, phy_id, + ax88796c_handle_link_change, + PHY_INTERFACE_MODE_MII); + if (IS_ERR(ax_local->phydev)) { + ret = PTR_ERR(ax_local->phydev); + goto err; + } + ax_local->phydev->irq = PHY_POLL; + + ret = devm_register_netdev(&spi->dev, ndev); + if (ret) { + dev_err(&spi->dev, "failed to register a network device\n"); + goto err_phy_dis; + } + + netif_info(ax_local, probe, ndev, "%s %s registered\n", + dev_driver_string(&spi->dev), + dev_name(&spi->dev)); + phy_attached_info(ax_local->phydev); + + return 0; + +err_phy_dis: + phy_disconnect(ax_local->phydev); +err: + return ret; +} + +static int ax88796c_remove(struct spi_device *spi) +{ + struct ax88796c_device *ax_local = dev_get_drvdata(&spi->dev); + struct net_device *ndev = ax_local->ndev; + + phy_disconnect(ndev->phydev); + + cancel_work_sync(&ax_local->ax_work); + + netif_info(ax_local, probe, ndev, "removing network device %s %s\n", + dev_driver_string(&spi->dev), + dev_name(&spi->dev)); + + return 0; +} + +static const struct of_device_id ax88796c_dt_ids[] = { + { .compatible = "asix,ax88796c" }, + {}, +}; +MODULE_DEVICE_TABLE(of, ax88796c_dt_ids); + +static const struct spi_device_id asix_id[] = { + { "ax88796c", 0 }, + { } +}; +MODULE_DEVICE_TABLE(spi, asix_id); + +static struct spi_driver ax88796c_spi_driver = { + .driver = { + .name = DRV_NAME, + .of_match_table = of_match_ptr(ax88796c_dt_ids), + }, + .probe = ax88796c_probe, + .remove = ax88796c_remove, + .id_table = asix_id, +}; + +static __init int ax88796c_spi_init(void) +{ + int ret; + + bitmap_zero(ax88796c_no_regs_mask, AX88796C_REGDUMP_LEN); + ret = bitmap_parse(no_regs_list, 35, + ax88796c_no_regs_mask, AX88796C_REGDUMP_LEN); + if (ret) { + bitmap_fill(ax88796c_no_regs_mask, AX88796C_REGDUMP_LEN); + pr_err("Invalid bitmap description, masking all registers\n"); + } + + return spi_register_driver(&ax88796c_spi_driver); +} + +static __exit void ax88796c_spi_exit(void) +{ + spi_unregister_driver(&ax88796c_spi_driver); +} + +module_init(ax88796c_spi_init); +module_exit(ax88796c_spi_exit); + +MODULE_AUTHOR("ASIX"); +MODULE_DESCRIPTION("ASIX AX88796C SPI Ethernet driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/asix/ax88796c_main.h b/drivers/net/ethernet/asix/ax88796c_main.h new file mode 100644 index 000000000000..80263c3cef75 --- /dev/null +++ b/drivers/net/ethernet/asix/ax88796c_main.h @@ -0,0 +1,568 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2010 ASIX Electronics Corporation + * Copyright (c) 2020 Samsung Electronics + * + * ASIX AX88796C SPI Fast Ethernet Linux driver + */ + +#ifndef _AX88796C_MAIN_H +#define _AX88796C_MAIN_H + +#include +#include + +#include "ax88796c_spi.h" + +/* These identify the driver base version and may not be removed. */ +#define DRV_NAME "ax88796c" +#define ADP_NAME "ASIX AX88796C SPI Ethernet Adapter" + +#define TX_QUEUE_HIGH_WATER 45 /* Tx queue high water mark */ +#define TX_QUEUE_LOW_WATER 20 /* Tx queue low water mark */ + +#define AX88796C_REGDUMP_LEN 256 +#define AX88796C_PHY_REGDUMP_LEN 14 +#define AX88796C_PHY_ID 0x10 + +#define TX_OVERHEAD 8 +#define TX_EOP_SIZE 4 + +#define AX_MCAST_FILTER_SIZE 8 +#define AX_MAX_MCAST 64 +#define AX_MAX_CLK 80000000 +#define TX_HDR_SOP_DICF 0x8000 +#define TX_HDR_SOP_CPHI 0x4000 +#define TX_HDR_SOP_INT 0x2000 +#define TX_HDR_SOP_MDEQ 0x1000 +#define TX_HDR_SOP_PKTLEN 0x07FF +#define TX_HDR_SOP_SEQNUM 0xF800 +#define TX_HDR_SOP_PKTLENBAR 0x07FF + +#define TX_HDR_SEG_FS 0x8000 +#define TX_HDR_SEG_LS 0x4000 +#define TX_HDR_SEG_SEGNUM 0x3800 +#define TX_HDR_SEG_SEGLEN 0x0700 +#define TX_HDR_SEG_EOFST 0xC000 +#define TX_HDR_SEG_SOFST 0x3800 +#define TX_HDR_SEG_SEGLENBAR 0x07FF + +#define TX_HDR_EOP_SEQNUM 0xF800 +#define TX_HDR_EOP_PKTLEN 0x07FF +#define TX_HDR_EOP_SEQNUMBAR 0xF800 +#define TX_HDR_EOP_PKTLENBAR 0x07FF + +/* Rx header fields mask */ +#define RX_HDR1_MCBC 0x8000 +#define RX_HDR1_STUFF_PKT 0x4000 +#define RX_HDR1_MII_ERR 0x2000 +#define RX_HDR1_CRC_ERR 0x1000 +#define RX_HDR1_PKT_LEN 0x07FF + +#define RX_HDR2_SEQ_NUM 0xF800 +#define RX_HDR2_PKT_LEN_BAR 0x7FFF + +#define RX_HDR3_PE 0x8000 +#define RX_HDR3_L3_TYPE_IPV4V6 0x6000 +#define RX_HDR3_L3_TYPE_IP 0x4000 +#define RX_HDR3_L3_TYPE_IPV6 0x2000 +#define RX_HDR3_L4_TYPE_ICMPV6 0x1400 +#define RX_HDR3_L4_TYPE_TCP 0x1000 +#define RX_HDR3_L4_TYPE_IGMP 0x0c00 +#define RX_HDR3_L4_TYPE_ICMP 0x0800 +#define RX_HDR3_L4_TYPE_UDP 0x0400 +#define RX_HDR3_L3_ERR 0x0200 +#define RX_HDR3_L4_ERR 0x0100 +#define RX_HDR3_PRIORITY(x) ((x) << 4) +#define RX_HDR3_STRIP 0x0008 +#define RX_HDR3_VLAN_ID 0x0007 + +struct ax88796c_pcpu_stats { + u64_stats_t rx_packets; + u64_stats_t rx_bytes; + u64_stats_t tx_packets; + u64_stats_t tx_bytes; + struct u64_stats_sync syncp; + u32 rx_dropped; + u32 tx_dropped; + u32 rx_frame_errors; + u32 rx_crc_errors; +}; + +struct ax88796c_device { + struct spi_device *spi; + struct net_device *ndev; + struct ax88796c_pcpu_stats __percpu *stats; + + struct work_struct ax_work; + + struct mutex spi_lock; /* device access */ + + struct sk_buff_head tx_wait_q; + + struct axspi_data ax_spi; + + struct mii_bus *mdiobus; + struct phy_device *phydev; + + int msg_enable; + + u16 seq_num; + + u8 multi_filter[AX_MCAST_FILTER_SIZE]; + + int link; + int speed; + int duplex; + int pause; + int asym_pause; + int flowctrl; + #define AX_FC_NONE 0 + #define AX_FC_RX BIT(0) + #define AX_FC_TX BIT(1) + #define AX_FC_ANEG BIT(2) + + u32 priv_flags; + #define AX_CAP_COMP BIT(0) + #define AX_PRIV_FLAGS_MASK (AX_CAP_COMP) + + unsigned long flags; + #define EVENT_INTR BIT(0) + #define EVENT_TX BIT(1) + #define EVENT_SET_MULTI BIT(2) + +}; + +#define to_ax88796c_device(ndev) ((struct ax88796c_device *)netdev_priv(ndev)) + +enum skb_state { + illegal = 0, + tx_done, + rx_done, + rx_err, +}; + +struct skb_data { + enum skb_state state; + size_t len; +}; + +/* A88796C register definition */ + /* Definition of PAGE0 */ +#define P0_PSR (0x00) + #define PSR_DEV_READY BIT(7) + #define PSR_RESET (0 << 15) + #define PSR_RESET_CLR BIT(15) +#define P0_BOR (0x02) +#define P0_FER (0x04) + #define FER_IPALM BIT(0) + #define FER_DCRC BIT(1) + #define FER_RH3M BIT(2) + #define FER_HEADERSWAP BIT(7) + #define FER_WSWAP BIT(8) + #define FER_BSWAP BIT(9) + #define FER_INTHI BIT(10) + #define FER_INTLO (0 << 10) + #define FER_IRQ_PULL BIT(11) + #define FER_RXEN BIT(14) + #define FER_TXEN BIT(15) +#define P0_ISR (0x06) + #define ISR_RXPKT BIT(0) + #define ISR_MDQ BIT(4) + #define ISR_TXT BIT(5) + #define ISR_TXPAGES BIT(6) + #define ISR_TXERR BIT(8) + #define ISR_LINK BIT(9) +#define P0_IMR (0x08) + #define IMR_RXPKT BIT(0) + #define IMR_MDQ BIT(4) + #define IMR_TXT BIT(5) + #define IMR_TXPAGES BIT(6) + #define IMR_TXERR BIT(8) + #define IMR_LINK BIT(9) + #define IMR_MASKALL (0xFFFF) + #define IMR_DEFAULT (IMR_TXERR) +#define P0_WFCR (0x0A) + #define WFCR_PMEIND BIT(0) /* PME indication */ + #define WFCR_PMETYPE BIT(1) /* PME I/O type */ + #define WFCR_PMEPOL BIT(2) /* PME polarity */ + #define WFCR_PMERST BIT(3) /* Reset PME */ + #define WFCR_SLEEP BIT(4) /* Enable sleep mode */ + #define WFCR_WAKEUP BIT(5) /* Enable wakeup mode */ + #define WFCR_WAITEVENT BIT(6) /* Reserved */ + #define WFCR_CLRWAKE BIT(7) /* Clear wakeup */ + #define WFCR_LINKCH BIT(8) /* Enable link change */ + #define WFCR_MAGICP BIT(9) /* Enable magic packet */ + #define WFCR_WAKEF BIT(10) /* Enable wakeup frame */ + #define WFCR_PMEEN BIT(11) /* Enable PME pin */ + #define WFCR_LINKCHS BIT(12) /* Link change status */ + #define WFCR_MAGICPS BIT(13) /* Magic packet status */ + #define WFCR_WAKEFS BIT(14) /* Wakeup frame status */ + #define WFCR_PMES BIT(15) /* PME pin status */ +#define P0_PSCR (0x0C) + #define PSCR_PS_MASK (0xFFF0) + #define PSCR_PS_D0 (0) + #define PSCR_PS_D1 BIT(0) + #define PSCR_PS_D2 BIT(1) + #define PSCR_FPS BIT(3) /* Enable fiber mode PS */ + #define PSCR_SWPS BIT(4) /* Enable software */ + /* PS control */ + #define PSCR_WOLPS BIT(5) /* Enable WOL PS */ + #define PSCR_SWWOL BIT(6) /* Enable software select */ + /* WOL PS */ + #define PSCR_PHYOSC BIT(7) /* Internal PHY OSC control */ + #define PSCR_FOFEF BIT(8) /* Force PHY generate FEF */ + #define PSCR_FOF BIT(9) /* Force PHY in fiber mode */ + #define PSCR_PHYPD BIT(10) /* PHY power down. */ + /* Active high */ + #define PSCR_PHYRST BIT(11) /* PHY reset signal. */ + /* Active low */ + #define PSCR_PHYCSIL BIT(12) /* PHY cable energy detect */ + #define PSCR_PHYCOFF BIT(13) /* PHY cable off */ + #define PSCR_PHYLINK BIT(14) /* PHY link status */ + #define PSCR_EEPOK BIT(15) /* EEPROM load complete */ +#define P0_MACCR (0x0E) + #define MACCR_RXEN BIT(0) /* Enable RX */ + #define MACCR_DUPLEX_FULL BIT(1) /* 1: Full, 0: Half */ + #define MACCR_SPEED_100 BIT(2) /* 1: 100Mbps, 0: 10Mbps */ + #define MACCR_RXFC_ENABLE BIT(3) + #define MACCR_RXFC_MASK 0xFFF7 + #define MACCR_TXFC_ENABLE BIT(4) + #define MACCR_TXFC_MASK 0xFFEF + #define MACCR_PSI BIT(6) /* Software Cable-Off */ + /* Power Saving Interrupt */ + #define MACCR_PF BIT(7) + #define MACCR_PMM_BITS 8 + #define MACCR_PMM_MASK (0x1F00) + #define MACCR_PMM_RESET BIT(8) + #define MACCR_PMM_WAIT (2 << 8) + #define MACCR_PMM_READY (3 << 8) + #define MACCR_PMM_D1 (4 << 8) + #define MACCR_PMM_D2 (5 << 8) + #define MACCR_PMM_WAKE (7 << 8) + #define MACCR_PMM_D1_WAKE (8 << 8) + #define MACCR_PMM_D2_WAKE (9 << 8) + #define MACCR_PMM_SLEEP (10 << 8) + #define MACCR_PMM_PHY_RESET (11 << 8) + #define MACCR_PMM_SOFT_D1 (16 << 8) + #define MACCR_PMM_SOFT_D2 (17 << 8) +#define P0_TFBFCR (0x10) + #define TFBFCR_SCHE_FREE_PAGE 0xE07F + #define TFBFCR_FREE_PAGE_BITS 0x07 + #define TFBFCR_FREE_PAGE_LATCH BIT(6) + #define TFBFCR_SET_FREE_PAGE(x) (((x) & 0x3F) << TFBFCR_FREE_PAGE_BITS) + #define TFBFCR_TX_PAGE_SET BIT(13) + #define TFBFCR_MANU_ENTX BIT(15) + #define TX_FREEBUF_MASK 0x003F + #define TX_DPTSTART 0x4000 + +#define P0_TSNR (0x12) + #define TXNR_TXB_ERR BIT(5) + #define TXNR_TXB_IDLE BIT(6) + #define TSNR_PKT_CNT(x) (((x) & 0x3F) << 8) + #define TXNR_TXB_REINIT BIT(14) + #define TSNR_TXB_START BIT(15) +#define P0_RTDPR (0x14) +#define P0_RXBCR1 (0x16) + #define RXBCR1_RXB_DISCARD BIT(14) + #define RXBCR1_RXB_START BIT(15) +#define P0_RXBCR2 (0x18) + #define RXBCR2_PKT_MASK (0xFF) + #define RXBCR2_RXPC_MASK (0x7F) + #define RXBCR2_RXB_READY BIT(13) + #define RXBCR2_RXB_IDLE BIT(14) + #define RXBCR2_RXB_REINIT BIT(15) +#define P0_RTWCR (0x1A) + #define RTWCR_RXWC_MASK (0x3FFF) + #define RTWCR_RX_LATCH BIT(15) +#define P0_RCPHR (0x1C) + + /* Definition of PAGE1 */ +#define P1_RPPER (0x22) + #define RPPER_RXEN BIT(0) +#define P1_MRCR (0x28) +#define P1_MDR (0x2A) +#define P1_RMPR (0x2C) +#define P1_TMPR (0x2E) +#define P1_RXBSPCR (0x30) + #define RXBSPCR_STUF_WORD_CNT(x) (((x) & 0x7000) >> 12) + #define RXBSPCR_STUF_ENABLE BIT(15) +#define P1_MCR (0x32) + #define MCR_SBP BIT(8) + #define MCR_SM BIT(9) + #define MCR_CRCENLAN BIT(11) + #define MCR_STP BIT(12) + /* Definition of PAGE2 */ +#define P2_CIR (0x42) +#define P2_PCR (0x44) + #define PCR_POLL_EN BIT(0) + #define PCR_POLL_FLOWCTRL BIT(1) + #define PCR_POLL_BMCR BIT(2) + #define PCR_PHYID(x) ((x) << 8) +#define P2_PHYSR (0x46) +#define P2_MDIODR (0x48) +#define P2_MDIOCR (0x4A) + #define MDIOCR_RADDR(x) ((x) & 0x1F) + #define MDIOCR_FADDR(x) (((x) & 0x1F) << 8) + #define MDIOCR_VALID BIT(13) + #define MDIOCR_READ BIT(14) + #define MDIOCR_WRITE BIT(15) +#define P2_LCR0 (0x4C) + #define LCR_LED0_EN BIT(0) + #define LCR_LED0_100MODE BIT(1) + #define LCR_LED0_DUPLEX BIT(2) + #define LCR_LED0_LINK BIT(3) + #define LCR_LED0_ACT BIT(4) + #define LCR_LED0_COL BIT(5) + #define LCR_LED0_10MODE BIT(6) + #define LCR_LED0_DUPCOL BIT(7) + #define LCR_LED1_EN BIT(8) + #define LCR_LED1_100MODE BIT(9) + #define LCR_LED1_DUPLEX BIT(10) + #define LCR_LED1_LINK BIT(11) + #define LCR_LED1_ACT BIT(12) + #define LCR_LED1_COL BIT(13) + #define LCR_LED1_10MODE BIT(14) + #define LCR_LED1_DUPCOL BIT(15) +#define P2_LCR1 (0x4E) + #define LCR_LED2_MASK (0xFF00) + #define LCR_LED2_EN BIT(0) + #define LCR_LED2_100MODE BIT(1) + #define LCR_LED2_DUPLEX BIT(2) + #define LCR_LED2_LINK BIT(3) + #define LCR_LED2_ACT BIT(4) + #define LCR_LED2_COL BIT(5) + #define LCR_LED2_10MODE BIT(6) + #define LCR_LED2_DUPCOL BIT(7) +#define P2_IPGCR (0x50) +#define P2_CRIR (0x52) +#define P2_FLHWCR (0x54) +#define P2_RXCR (0x56) + #define RXCR_PRO BIT(0) + #define RXCR_AMALL BIT(1) + #define RXCR_SEP BIT(2) + #define RXCR_AB BIT(3) + #define RXCR_AM BIT(4) + #define RXCR_AP BIT(5) + #define RXCR_ARP BIT(6) +#define P2_JLCR (0x58) +#define P2_MPLR (0x5C) + + /* Definition of PAGE3 */ +#define P3_MACASR0 (0x62) + #define P3_MACASR(x) (P3_MACASR0 + 2 * (x)) + #define MACASR_LOWBYTE_MASK 0x00FF + #define MACASR_HIGH_BITS 0x08 +#define P3_MACASR1 (0x64) +#define P3_MACASR2 (0x66) +#define P3_MFAR01 (0x68) +#define P3_MFAR_BASE (0x68) + #define P3_MFAR(x) (P3_MFAR_BASE + 2 * (x)) + +#define P3_MFAR23 (0x6A) +#define P3_MFAR45 (0x6C) +#define P3_MFAR67 (0x6E) +#define P3_VID0FR (0x70) +#define P3_VID1FR (0x72) +#define P3_EECSR (0x74) +#define P3_EEDR (0x76) +#define P3_EECR (0x78) + #define EECR_ADDR_MASK (0x00FF) + #define EECR_READ_ACT BIT(8) + #define EECR_WRITE_ACT BIT(9) + #define EECR_WRITE_DISABLE BIT(10) + #define EECR_WRITE_ENABLE BIT(11) + #define EECR_EE_READY BIT(13) + #define EECR_RELOAD BIT(14) + #define EECR_RESET BIT(15) +#define P3_TPCR (0x7A) + #define TPCR_PATT_MASK (0xFF) + #define TPCR_RAND_PKT_EN BIT(14) + #define TPCR_FIXED_PKT_EN BIT(15) +#define P3_TPLR (0x7C) + /* Definition of PAGE4 */ +#define P4_SPICR (0x8A) + #define SPICR_RCEN BIT(0) + #define SPICR_QCEN BIT(1) + #define SPICR_RBRE BIT(3) + #define SPICR_PMM BIT(4) + #define SPICR_LOOPBACK BIT(8) + #define SPICR_CORE_RES_CLR BIT(10) + #define SPICR_SPI_RES_CLR BIT(11) +#define P4_SPIISMR (0x8C) + +#define P4_COERCR0 (0x92) + #define COERCR0_RXIPCE BIT(0) + #define COERCR0_RXIPVE BIT(1) + #define COERCR0_RXV6PE BIT(2) + #define COERCR0_RXTCPE BIT(3) + #define COERCR0_RXUDPE BIT(4) + #define COERCR0_RXICMP BIT(5) + #define COERCR0_RXIGMP BIT(6) + #define COERCR0_RXICV6 BIT(7) + + #define COERCR0_RXTCPV6 BIT(8) + #define COERCR0_RXUDPV6 BIT(9) + #define COERCR0_RXICMV6 BIT(10) + #define COERCR0_RXIGMV6 BIT(11) + #define COERCR0_RXICV6V6 BIT(12) + + #define COERCR0_DEFAULT (COERCR0_RXIPCE | COERCR0_RXV6PE | \ + COERCR0_RXTCPE | COERCR0_RXUDPE | \ + COERCR0_RXTCPV6 | COERCR0_RXUDPV6) +#define P4_COERCR1 (0x94) + #define COERCR1_IPCEDP BIT(0) + #define COERCR1_IPVEDP BIT(1) + #define COERCR1_V6VEDP BIT(2) + #define COERCR1_TCPEDP BIT(3) + #define COERCR1_UDPEDP BIT(4) + #define COERCR1_ICMPDP BIT(5) + #define COERCR1_IGMPDP BIT(6) + #define COERCR1_ICV6DP BIT(7) + #define COERCR1_RX64TE BIT(8) + #define COERCR1_RXPPPE BIT(9) + #define COERCR1_TCP6DP BIT(10) + #define COERCR1_UDP6DP BIT(11) + #define COERCR1_IC6DP BIT(12) + #define COERCR1_IG6DP BIT(13) + #define COERCR1_ICV66DP BIT(14) + #define COERCR1_RPCE BIT(15) + + #define COERCR1_DEFAULT (COERCR1_RXPPPE) + +#define P4_COETCR0 (0x96) + #define COETCR0_TXIP BIT(0) + #define COETCR0_TXTCP BIT(1) + #define COETCR0_TXUDP BIT(2) + #define COETCR0_TXICMP BIT(3) + #define COETCR0_TXIGMP BIT(4) + #define COETCR0_TXICV6 BIT(5) + #define COETCR0_TXTCPV6 BIT(8) + #define COETCR0_TXUDPV6 BIT(9) + #define COETCR0_TXICMV6 BIT(10) + #define COETCR0_TXIGMV6 BIT(11) + #define COETCR0_TXICV6V6 BIT(12) + + #define COETCR0_DEFAULT (COETCR0_TXIP | COETCR0_TXTCP | \ + COETCR0_TXUDP | COETCR0_TXTCPV6 | \ + COETCR0_TXUDPV6) +#define P4_COETCR1 (0x98) + #define COETCR1_TX64TE BIT(0) + #define COETCR1_TXPPPE BIT(1) + +#define P4_COECEDR (0x9A) +#define P4_L2CECR (0x9C) + + /* Definition of PAGE5 */ +#define P5_WFTR (0xA2) + #define WFTR_2MS (0x01) + #define WFTR_4MS (0x02) + #define WFTR_8MS (0x03) + #define WFTR_16MS (0x04) + #define WFTR_32MS (0x05) + #define WFTR_64MS (0x06) + #define WFTR_128MS (0x07) + #define WFTR_256MS (0x08) + #define WFTR_512MS (0x09) + #define WFTR_1024MS (0x0A) + #define WFTR_2048MS (0x0B) + #define WFTR_4096MS (0x0C) + #define WFTR_8192MS (0x0D) + #define WFTR_16384MS (0x0E) + #define WFTR_32768MS (0x0F) +#define P5_WFCCR (0xA4) +#define P5_WFCR03 (0xA6) + #define WFCR03_F0_EN BIT(0) + #define WFCR03_F1_EN BIT(4) + #define WFCR03_F2_EN BIT(8) + #define WFCR03_F3_EN BIT(12) +#define P5_WFCR47 (0xA8) + #define WFCR47_F4_EN BIT(0) + #define WFCR47_F5_EN BIT(4) + #define WFCR47_F6_EN BIT(8) + #define WFCR47_F7_EN BIT(12) +#define P5_WF0BMR0 (0xAA) +#define P5_WF0BMR1 (0xAC) +#define P5_WF0CR (0xAE) +#define P5_WF0OBR (0xB0) +#define P5_WF1BMR0 (0xB2) +#define P5_WF1BMR1 (0xB4) +#define P5_WF1CR (0xB6) +#define P5_WF1OBR (0xB8) +#define P5_WF2BMR0 (0xBA) +#define P5_WF2BMR1 (0xBC) + + /* Definition of PAGE6 */ +#define P6_WF2CR (0xC2) +#define P6_WF2OBR (0xC4) +#define P6_WF3BMR0 (0xC6) +#define P6_WF3BMR1 (0xC8) +#define P6_WF3CR (0xCA) +#define P6_WF3OBR (0xCC) +#define P6_WF4BMR0 (0xCE) +#define P6_WF4BMR1 (0xD0) +#define P6_WF4CR (0xD2) +#define P6_WF4OBR (0xD4) +#define P6_WF5BMR0 (0xD6) +#define P6_WF5BMR1 (0xD8) +#define P6_WF5CR (0xDA) +#define P6_WF5OBR (0xDC) + +/* Definition of PAGE7 */ +#define P7_WF6BMR0 (0xE2) +#define P7_WF6BMR1 (0xE4) +#define P7_WF6CR (0xE6) +#define P7_WF6OBR (0xE8) +#define P7_WF7BMR0 (0xEA) +#define P7_WF7BMR1 (0xEC) +#define P7_WF7CR (0xEE) +#define P7_WF7OBR (0xF0) +#define P7_WFR01 (0xF2) +#define P7_WFR23 (0xF4) +#define P7_WFR45 (0xF6) +#define P7_WFR67 (0xF8) +#define P7_WFPC0 (0xFA) +#define P7_WFPC1 (0xFC) + +/* Tx headers structure */ +struct tx_sop_header { + /* bit 15-11: flags, bit 10-0: packet length */ + u16 flags_len; + /* bit 15-11: sequence number, bit 11-0: packet length bar */ + u16 seq_lenbar; +}; + +struct tx_segment_header { + /* bit 15-14: flags, bit 13-11: segment number */ + /* bit 10-0: segment length */ + u16 flags_seqnum_seglen; + /* bit 15-14: end offset, bit 13-11: start offset */ + /* bit 10-0: segment length bar */ + u16 eo_so_seglenbar; +}; + +struct tx_eop_header { + /* bit 15-11: sequence number, bit 10-0: packet length */ + u16 seq_len; + /* bit 15-11: sequence number bar, bit 10-0: packet length bar */ + u16 seqbar_lenbar; +}; + +struct tx_pkt_info { + struct tx_sop_header sop; + struct tx_segment_header seg; + struct tx_eop_header eop; + u16 pkt_len; + u16 seq_num; +}; + +/* Rx headers structure */ +struct rx_header { + u16 flags_len; + u16 seq_lenbar; + u16 flags; +}; + +extern unsigned long ax88796c_no_regs_mask[]; + +#endif /* #ifndef _AX88796C_MAIN_H */ diff --git a/drivers/net/ethernet/asix/ax88796c_spi.c b/drivers/net/ethernet/asix/ax88796c_spi.c new file mode 100644 index 000000000000..1252a97d1c52 --- /dev/null +++ b/drivers/net/ethernet/asix/ax88796c_spi.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2010 ASIX Electronics Corporation + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * ASIX AX88796C SPI Fast Ethernet Linux driver + */ + +#define pr_fmt(fmt) "ax88796c: " fmt + +#include +#include + +#include "ax88796c_spi.h" + +const u8 ax88796c_rx_cmd_buf[5] = {AX_SPICMD_READ_RXQ, 0xFF, 0xFF, 0xFF, 0xFF}; +const u8 ax88796c_tx_cmd_buf[4] = {AX_SPICMD_WRITE_TXQ, 0xFF, 0xFF, 0xFF}; + +/* driver bus management functions */ +int axspi_wakeup(struct axspi_data *ax_spi) +{ + int ret; + + ax_spi->cmd_buf[0] = AX_SPICMD_EXIT_PWD; /* OP */ + ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 1); + if (ret) + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); + return ret; +} + +int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status) +{ + int ret; + + /* OP */ + ax_spi->cmd_buf[0] = AX_SPICMD_READ_STATUS; + ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)&status, 3); + if (ret) + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); + else + le16_to_cpus(&status->isr); + + return ret; +} + +int axspi_read_rxq(struct axspi_data *ax_spi, void *data, int len) +{ + struct spi_transfer *xfer = ax_spi->spi_rx_xfer; + int ret; + + memcpy(ax_spi->cmd_buf, ax88796c_rx_cmd_buf, 5); + + xfer->tx_buf = ax_spi->cmd_buf; + xfer->rx_buf = NULL; + xfer->len = ax_spi->comp ? 2 : 5; + xfer->bits_per_word = 8; + spi_message_add_tail(xfer, &ax_spi->rx_msg); + + xfer++; + xfer->rx_buf = data; + xfer->tx_buf = NULL; + xfer->len = len; + xfer->bits_per_word = 8; + spi_message_add_tail(xfer, &ax_spi->rx_msg); + ret = spi_sync(ax_spi->spi, &ax_spi->rx_msg); + if (ret) + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); + + return ret; +} + +int axspi_write_txq(const struct axspi_data *ax_spi, void *data, int len) +{ + return spi_write(ax_spi->spi, data, len); +} + +u16 axspi_read_reg(struct axspi_data *ax_spi, u8 reg) +{ + int ret; + int len = ax_spi->comp ? 3 : 4; + + ax_spi->cmd_buf[0] = 0x03; /* OP code read register */ + ax_spi->cmd_buf[1] = reg; /* register address */ + ax_spi->cmd_buf[2] = 0xFF; /* dumy cycle */ + ax_spi->cmd_buf[3] = 0xFF; /* dumy cycle */ + ret = spi_write_then_read(ax_spi->spi, + ax_spi->cmd_buf, len, + ax_spi->rx_buf, 2); + if (ret) { + dev_err(&ax_spi->spi->dev, + "%s() failed: ret = %d\n", __func__, ret); + return 0xFFFF; + } + + le16_to_cpus(ax_spi->rx_buf); + + return *(u16 *)ax_spi->rx_buf; +} + +int axspi_write_reg(struct axspi_data *ax_spi, u8 reg, u16 value) +{ + int ret; + + memset(ax_spi->cmd_buf, 0, sizeof(ax_spi->cmd_buf)); + ax_spi->cmd_buf[0] = AX_SPICMD_WRITE_REG; /* OP code read register */ + ax_spi->cmd_buf[1] = reg; /* register address */ + ax_spi->cmd_buf[2] = value; + ax_spi->cmd_buf[3] = value >> 8; + + ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 4); + if (ret) + dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); + return ret; +} + diff --git a/drivers/net/ethernet/asix/ax88796c_spi.h b/drivers/net/ethernet/asix/ax88796c_spi.h new file mode 100644 index 000000000000..5bcf91f603fb --- /dev/null +++ b/drivers/net/ethernet/asix/ax88796c_spi.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2010 ASIX Electronics Corporation + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * ASIX AX88796C SPI Fast Ethernet Linux driver + */ + +#ifndef _AX88796C_SPI_H +#define _AX88796C_SPI_H + +#include +#include + +/* Definition of SPI command */ +#define AX_SPICMD_WRITE_TXQ 0x02 +#define AX_SPICMD_READ_REG 0x03 +#define AX_SPICMD_READ_STATUS 0x05 +#define AX_SPICMD_READ_RXQ 0x0B +#define AX_SPICMD_BIDIR_WRQ 0xB2 +#define AX_SPICMD_WRITE_REG 0xD8 +#define AX_SPICMD_EXIT_PWD 0xAB + +extern const u8 ax88796c_rx_cmd_buf[]; +extern const u8 ax88796c_tx_cmd_buf[]; + +struct axspi_data { + struct spi_device *spi; + struct spi_message rx_msg; + struct spi_transfer spi_rx_xfer[2]; + u8 cmd_buf[6]; + u8 rx_buf[6]; + u8 comp; +}; + +struct spi_status { + u16 isr; + u8 status; +# define AX_STATUS_READY 0x80 +}; + +int axspi_read_rxq(struct axspi_data *ax_spi, void *data, int len); +int axspi_write_txq(const struct axspi_data *ax_spi, void *data, int len); +u16 axspi_read_reg(struct axspi_data *ax_spi, u8 reg); +int axspi_write_reg(struct axspi_data *ax_spi, u8 reg, u16 value); +int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status); +int axspi_wakeup(struct axspi_data *ax_spi); + +static inline u16 AX_READ(struct axspi_data *ax_spi, u8 offset) +{ + return axspi_read_reg(ax_spi, offset); +} + +static inline int AX_WRITE(struct axspi_data *ax_spi, u16 value, u8 offset) +{ + return axspi_write_reg(ax_spi, offset, value); +} + +static inline int AX_READ_STATUS(struct axspi_data *ax_spi, + struct spi_status *status) +{ + return axspi_read_status(ax_spi, status); +} + +static inline int AX_WAKEUP(struct axspi_data *ax_spi) +{ + return axspi_wakeup(ax_spi); +} +#endif -- 2.26.2 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=-22.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE, 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 39BA0C433ED for ; Fri, 7 May 2021 14:04:31 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 1EBA06141E for ; Fri, 7 May 2021 14:04:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1EBA06141E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=samsung.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:MIME-Version:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=f3wTfU6v/qS5fpUJAZJbLY7ZJ+MXNRVma1Dg4NQ4+rI=; b=iFpEK79ye3htRxHoC8khScQcd oHnOK18NZlVWzs8qNcbgH6vNIWHLRV5sdooVRxmuq6tA/B4aDL7CBhWLwFVf7KGdrn4nt4cbh+rAo 92NhXL5W207zBzb0wlztr/yoXLRBb7NdBdxWospcXS09FOFFBWA/5nQE3v6ww19xg0GRMOmCH27Y1 d2Pz2xJ3vY8MMox+JPdBdYXQUiK6lgp8bBtQBbivnGAu1XpSjAKvMeu7ZAmSKjukff0Ylnk/qjesu fhCilAp/xpWbJvccnWYTL8niQvFFYLcJFi477iwS8gTisSlXrWaZys9zBEu5vW0o4YMKCdAoxQra8 g1qn/LUSw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lf13Z-007Esn-T9; Fri, 07 May 2021 14:02:18 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lf12s-007EnS-BJ for linux-arm-kernel@desiato.infradead.org; Fri, 07 May 2021 14:01:35 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:Content-Type: Content-Transfer-Encoding:MIME-Version:In-Reply-To:Message-Id:Date:Subject:Cc :To:From:Sender:Reply-To:Content-ID:Content-Description; bh=ny6IYZbd4LSHmOSrccvVvvtDUZwgDQtJI4viqmbR7nk=; b=gp3rixfe3U9PwWPPOLr5jwBjA7 WV7n2tX0pycS9CwWXGTW+l4QdS23nwp7iI2UcTB/DRfmjdRfgfXSKyl3Aj/xv4hJcCukr/B8HHQOf C0rYfvLyyqL6N/jvn9NgG0Rgz4UCCHJVgHouhVrQOjLOYvQmLoYdm4gmxDccI6+ti7yRS6DEt1Df6 n061ukG4Wh186ZwMcXEx7V4lY+I0fNcppIn/GZCondARIBKvEHGZK3KXKnzlac7y1euN24GsOEoSn FCMMwXStkzDudksvX7E8Jq3pbbJlBCP+TuWqizap6hn2zNq8r7D+vj9WXnpnoS0An2cHMccbtNCAN 2UbLVvFA==; Received: from mailout1.w1.samsung.com ([210.118.77.11]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lf12i-006uF7-U1 for linux-arm-kernel@lists.infradead.org; Fri, 07 May 2021 14:01:33 +0000 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20210507140115euoutp01a6196de2ac2f2013828ddaabc23ae48c~8zaVHZxOZ1061410614euoutp01u for ; Fri, 7 May 2021 14:01:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20210507140115euoutp01a6196de2ac2f2013828ddaabc23ae48c~8zaVHZxOZ1061410614euoutp01u DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1620396075; bh=ny6IYZbd4LSHmOSrccvVvvtDUZwgDQtJI4viqmbR7nk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r9GVYiQ/4o/QHRmlDdGYuw0AGPzGnf1cSOlxooUP2V0goF0RjNMMTAhbcdyPPe8XG Dq2p4R9/m/tWONHYF06Jl59s777uwGTcOfKmd0BJe6Mv35a4kaANwL770JetVcKLQK UPDwdd8NlrYDaU7/At/C7SgHKOuq40rdHNrl6qNk= Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20210507140115eucas1p25cd3df26b201033c80b032b027c3c358~8zaUe8ojW2125021250eucas1p2m; Fri, 7 May 2021 14:01:15 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id B8.37.09444.A2845906; Fri, 7 May 2021 15:01:14 +0100 (BST) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20210507140114eucas1p23b94a5fdf2d50813999a6d4a9a44731f~8zaT2Er6R0929309293eucas1p23; Fri, 7 May 2021 14:01:14 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20210507140114eusmtrp1dcea52fee4ab85feffa5173186cc530e~8zaT1BmJg3065730657eusmtrp1S; Fri, 7 May 2021 14:01:14 +0000 (GMT) X-AuditID: cbfec7f4-dbdff700000024e4-ab-6095482acbaf Received: from eusmtip1.samsung.com ( [203.254.199.221]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id D5.49.08696.A2845906; Fri, 7 May 2021 15:01:14 +0100 (BST) Received: from localhost (unknown [106.120.51.46]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20210507140114eusmtip1b4c42f967ceef5facb75d6b868f7e2df~8zaTiaMkt2247722477eusmtip11; Fri, 7 May 2021 14:01:13 +0000 (GMT) From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= To: Andrew Lunn , jim.cromie@gmail.com, Heiner Kallweit , "David S. Miller" , Jakub Kicinski , Rob Herring , Kukjin Kim , Krzysztof Kozlowski , Russell King , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org Cc: =?UTF-8?q?Bart=C5=82omiej=20=C5=BBolnierkiewicz?= , Marek Szyprowski , =?UTF-8?q?=C5=81ukasz=20Stelmach?= Subject: [PATCH net-next v12 3/3] net: ax88796c: ASIX AX88796C SPI Ethernet Adapter Driver Date: Fri, 7 May 2021 16:01:10 +0200 Message-Id: <20210507140110.6323-4-l.stelmach@samsung.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210507140110.6323-1-l.stelmach@samsung.com> MIME-Version: 1.0 Organization: Samsung R&D Institute Poland X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrCKsWRmVeSWpSXmKPExsWy7djP87paHlMTDJ6dNbE4f/cQs8XGGetZ Leacb2GxmH/kHKvFovczWC2uvb3DatH/+DWzxfnzG9gtLmzrY7W4eWgFo8Wmx9dYLS7vmsNm MeP8PiaLQ1P3MlqsPXKX3eLYAjGL1r1H2B0EPS5fu8jssWXlTSaPnbPusntsWtXJ5rF5Sb3H zh2fmTz6tqxi9Pi8SS6AI4rLJiU1J7MstUjfLoErY+q2HcwFG6ayVMxceI61gbFvB3MXIyeH hICJxKkjX1i6GLk4hARWMErc/LGWCcL5wijx/uAmdgjnM6PE37NtjDAtT6+3QVUtZ5TYcHgX G4TznFFiyvHp7CBVbAKOEv1LT7CCJEQE7jFLrG9/wAjiMAvsY5TYeW8K2HphgRiJ5+vnsYLY LAKqEs9m/wWzeQWsJJ4cn8AOsU9eon35djYQm1PAWuLBp7vsEDWCEidnPmEBsfkFtCTWNF0H s5mB6pu3zmYGWSYhsJ9TYtKORSwQg1wknn/5yQphC0u8Or4FaoGMxOnJPUA1HEB2vcTkSWYQ vT2MEtvm/IDqtZa4c+4XG0gNs4CmxPpd+hBhR4k9r7qYIVr5JG68FYQ4gU9i0rbpUGFeiY42 IYhqFYl1/XugBkpJ9L5awTiBUWkWkmdmIXlgFsKuBYzMqxjFU0uLc9NTi43yUsv1ihNzi0vz 0vWS83M3MQIT3ul/x7/sYFz+6qPeIUYmDsZDjBIczEoivKcXTU4Q4k1JrKxKLcqPLyrNSS0+ xCjNwaIkzpu0ZU28kEB6YklqdmpqQWoRTJaJg1OqgWmN7MXg/z2hZ5fI7mx9+XMLl1uP99X/ i3eui5J773Rg0ZLUuLNRN+rq7SoiZ9+tOylSuOjX7Tr78uC4O/6rNPiFO/RXRNkuY/1x9vPl ktlT2+4w5J5mOLCJe93Te7Mz3sQr50YuOa93eYL3HcmCZ0dEP23NFGFmdYq8N3d5dgiLauyX qLMcCupp5/eesbM7xu8guvTjIbvVUybfZHLfd1VtQaeE8OVfb3bNn8+j9nCNNMfr7YyRU3x3 Xoh352zqyPbkmrH+u9JK9hWzPk9tTnlzcrLbVvOI3EXVXxuuv9p8yOX96p3x7KE1hsYZy/c2 uh1sPiWtkS15ZS/bVPHfO3Sq15y5rhMYof3Q0Pn13ZV6SizFGYmGWsxFxYkAxEM64ucDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrMIsWRmVeSWpSXmKPExsVy+t/xu7paHlMTDGad57Y4f/cQs8XGGetZ Leacb2GxmH/kHKvFovczWC2uvb3DatH/+DWzxfnzG9gtLmzrY7W4eWgFo8Wmx9dYLS7vmsNm MeP8PiaLQ1P3MlqsPXKX3eLYAjGL1r1H2B0EPS5fu8jssWXlTSaPnbPusntsWtXJ5rF5Sb3H zh2fmTz6tqxi9Pi8SS6AI0rPpii/tCRVISO/uMRWKdrQwkjP0NJCz8jEUs/Q2DzWyshUSd/O JiU1J7MstUjfLkEvY+q2HcwFG6ayVMxceI61gbFvB3MXIyeHhICJxNPrbUxdjFwcQgJLGSW6 P95h6WLkAEpISaycmw5RIyzx51oXG0TNU0aJOcfnsIEk2AQcJfqXnmAFSYgIvGGWaLr3lh3E YRbYxyix/+hidpBJwgJREq07LUAaWARUJZ7N/ssKYvMKWEk8OT6BHWKDvET78u1gQzkFrCUe fLoLFhcCqpm4qZMJol5Q4uTMJ2DHMQuoS6yfJwQS5hfQkljTdJ0FxGYGGtO8dTbzBEahWUg6 ZiF0zEJStYCReRWjSGppcW56brGRXnFibnFpXrpecn7uJkZgbG879nPLDsaVrz7qHWJk4mA8 xCjBwawkwnt60eQEId6UxMqq1KL8+KLSnNTiQ4ymQJ9NZJYSTc4HJpe8knhDMwNTQxMzSwNT SzNjJXFekyNr4oUE0hNLUrNTUwtSi2D6mDg4pRqYNtiJbPdxdOPqST20PEPuptved9nM3899 284VdXLj0fbn7g27T38M+3RlTdWCm/+5uR8IFMzRv3Xd91Zt0MWUUAbDHQdv5lwKeO/jJno0 zd764Dyrgi0S60+/enR9u6/kBDUdoWk8Wh3Hu4Jf31Feplz7dn+RnmXbpz0dqvyHep0ytK+q 16+d4p1Z/CxULbPJSu26buyuB6nGkkWvl/5RYc/avZXHhuWq/5mp9Uc+L30cMslSxp0ly/pj nfz0w8ve1JlteMTTw+U0S32WlGz42onra7Lm3riiJzvjIL9b0DWBoicnD2mf+/Sqh1dw3fGt 7R/Xxx0tfFFrIrU/j0NkGd/sPNUP0ypO/njC9eT6MyWW4oxEQy3mouJEAA6HHyp2AwAA X-CMS-MailID: 20210507140114eucas1p23b94a5fdf2d50813999a6d4a9a44731f X-Msg-Generator: CA X-RootMTR: 20210507140114eucas1p23b94a5fdf2d50813999a6d4a9a44731f X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20210507140114eucas1p23b94a5fdf2d50813999a6d4a9a44731f References: <20210507140110.6323-1-l.stelmach@samsung.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210507_070125_453225_FDA0B0AF X-CRM114-Status: GOOD ( 28.93 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org QVNJWCBBWDg4Nzk2WzFdIGlzIGEgdmVyc2F0aWxlIGV0aGVybmV0IGFkYXB0ZXIgY2hpcCwgdGhh dCBjYW4gYmUKY29ubmVjdGVkIHRvIGEgQ1BVIHdpdGggYSA4LzE2LWJpdCBidXMgb3Igd2l0aCBh biBTUEkuIFRoaXMgZHJpdmVyCnN1cHBvcnRzIFNQSSBjb25uZWN0aW9uLgoKVGhlIGRyaXZlciBo YXMgYmVlbiBwb3J0ZWQgZnJvbSB0aGUgdmVuZG9yIGtlcm5lbCBmb3IgQVJUSUs1WzJdCmJvYXJk cy4gU2V2ZXJhbCBjaGFuZ2VzIHdlcmUgbWFkZSB0byBhZGFwdCBpdCB0byB0aGUgY3VycmVudCBr ZXJuZWwKd2hpY2ggaW5jbHVkZToKCisgdXBkYXRlZCBEVCBjb25maWd1cmF0aW9uLAorIGNsb2Nr IGNvbmZpZ3VyYXRpb24gbW92ZWQgdG8gRFQsCisgbmV3IHRpbWVyLCBldGh0b29sIGFuZCBncGlv IEFQSXMsCisgZGV2XyogaW5zdGVhZCBvZiBwcl8qIGFuZCBjdXN0b20gcHJpbnRrKCkgd3JhcHBl cnMsCisgcmVtb3ZlZCBhd2t3YXJkIHZlbmRvciBwb3dlciBtYW5hZ2VtdG4uCisgaW50cm9kdWNl ZCBldGh0b29sIHR1bmFibGUgdG8gY29udHJvbCBTUEkgY29tcHJlc3Npb24KClsxXSBodHRwczov L3d3dy5hc2l4LmNvbS50dy9wcm9kdWN0cy5waHA/b3A9cEl0ZW1kZXRhaWwmUEl0ZW1JRD0xMDQ7 NjU7ODYmUExpbmU9NjUKWzJdIGh0dHBzOi8vZ2l0LnRpemVuLm9yZy9jZ2l0L3Byb2ZpbGUvY29t bW9uL3BsYXRmb3JtL2tlcm5lbC9saW51eC0zLjEwLWFydGlrLwoKVGhlIG90aGVyIGF4ODg3OTYg ZHJpdmVyIGlzIGZvciBORTIwMDAgY29tcGF0aWJsZSBBWDg4Nzk2TCBjaGlwLiBUaGVzZQpjaGlw cyBhcmUgbm90IGNvbXBhdGlibGUuIEhlbmNlLCB0d28gc2VwYXJhdGUgZHJpdmVycyBhcmUgcmVx dWlyZWQuCgpTaWduZWQtb2ZmLWJ5OiDFgXVrYXN6IFN0ZWxtYWNoIDxsLnN0ZWxtYWNoQHNhbXN1 bmcuY29tPgpSZXZpZXdlZC1ieTogQW5kcmV3IEx1bm4gPGFuZHJld0BsdW5uLmNoPgotLS0KIE1B SU5UQUlORVJTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDYgKwogZHJpdmVy cy9uZXQvZXRoZXJuZXQvS2NvbmZpZyAgICAgICAgICAgICAgIHwgICAgMSArCiBkcml2ZXJzL25l dC9ldGhlcm5ldC9NYWtlZmlsZSAgICAgICAgICAgICAgfCAgICAxICsKIGRyaXZlcnMvbmV0L2V0 aGVybmV0L2FzaXgvS2NvbmZpZyAgICAgICAgICB8ICAgMzUgKwogZHJpdmVycy9uZXQvZXRoZXJu ZXQvYXNpeC9NYWtlZmlsZSAgICAgICAgIHwgICAgNiArCiBkcml2ZXJzL25ldC9ldGhlcm5ldC9h c2l4L2F4ODg3OTZjX2lvY3RsLmMgfCAgMjM5ICsrKysKIGRyaXZlcnMvbmV0L2V0aGVybmV0L2Fz aXgvYXg4ODc5NmNfaW9jdGwuaCB8ICAgMjYgKwogZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9h eDg4Nzk2Y19tYWluLmMgIHwgMTE0NiArKysrKysrKysrKysrKysrKysrKwogZHJpdmVycy9uZXQv ZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19tYWluLmggIHwgIDU2OCArKysrKysrKysrCiBkcml2ZXJz L25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX3NwaS5jICAgfCAgMTE1ICsrCiBkcml2ZXJzL25l dC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX3NwaS5oICAgfCAgIDY5ICsrCiAxMSBmaWxlcyBjaGFu Z2VkLCAyMjEyIGluc2VydGlvbnMoKykKIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL25ldC9l dGhlcm5ldC9hc2l4L0tjb25maWcKIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL25ldC9ldGhl cm5ldC9hc2l4L01ha2VmaWxlCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9uZXQvZXRoZXJu ZXQvYXNpeC9heDg4Nzk2Y19pb2N0bC5jCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9uZXQv ZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19pb2N0bC5oCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy cy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19tYWluLmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBk cml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX21haW4uaAogY3JlYXRlIG1vZGUgMTAw NjQ0IGRyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfc3BpLmMKIGNyZWF0ZSBtb2Rl IDEwMDY0NCBkcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX3NwaS5oCgpkaWZmIC0t Z2l0IGEvTUFJTlRBSU5FUlMgYi9NQUlOVEFJTkVSUwppbmRleCA0Nzk2Y2NmOWY4NzEuLjVlMzY0 NGYyNTQwNiAxMDA2NDQKLS0tIGEvTUFJTlRBSU5FUlMKKysrIGIvTUFJTlRBSU5FUlMKQEAgLTI4 MTQsNiArMjgxNCwxMiBAQCBTOglNYWludGFpbmVkCiBGOglEb2N1bWVudGF0aW9uL2h3bW9uL2Fz Yzc2MjEucnN0CiBGOglkcml2ZXJzL2h3bW9uL2FzYzc2MjEuYwogCitBU0lYIEFYODg3OTZDIFNQ SSBFVEhFUk5FVCBBREFQVEVSCitNOgnFgXVrYXN6IFN0ZWxtYWNoIDxsLnN0ZWxtYWNoQHNhbXN1 bmcuY29tPgorUzoJTWFpbnRhaW5lZAorRjoJRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRp bmdzL25ldC9hc2l4LGF4ODg3OTZjLnlhbWwKK0Y6CWRyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgv YXg4ODc5NmNfKgorCiBBU1BFRUQgUElOQ1RSTCBEUklWRVJTCiBNOglBbmRyZXcgSmVmZmVyeSA8 YW5kcmV3QGFqLmlkLmF1PgogTDoJbGludXgtYXNwZWVkQGxpc3RzLm96bGFicy5vcmcgKG1vZGVy YXRlZCBmb3Igbm9uLXN1YnNjcmliZXJzKQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvZXRoZXJu ZXQvS2NvbmZpZyBiL2RyaXZlcnMvbmV0L2V0aGVybmV0L0tjb25maWcKaW5kZXggMWNkZmYxZGNh NzkwLi5jNDQ0NzI3NGM5ZGUgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L0tjb25m aWcKKysrIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvS2NvbmZpZwpAQCAtMzMsNiArMzMsNyBAQCBz b3VyY2UgImRyaXZlcnMvbmV0L2V0aGVybmV0L2FwbS9LY29uZmlnIgogc291cmNlICJkcml2ZXJz L25ldC9ldGhlcm5ldC9hcHBsZS9LY29uZmlnIgogc291cmNlICJkcml2ZXJzL25ldC9ldGhlcm5l dC9hcXVhbnRpYS9LY29uZmlnIgogc291cmNlICJkcml2ZXJzL25ldC9ldGhlcm5ldC9hcmMvS2Nv bmZpZyIKK3NvdXJjZSAiZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9LY29uZmlnIgogc291cmNl ICJkcml2ZXJzL25ldC9ldGhlcm5ldC9hdGhlcm9zL0tjb25maWciCiBzb3VyY2UgImRyaXZlcnMv bmV0L2V0aGVybmV0L2Jyb2FkY29tL0tjb25maWciCiBzb3VyY2UgImRyaXZlcnMvbmV0L2V0aGVy bmV0L2Jyb2NhZGUvS2NvbmZpZyIKZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L01h a2VmaWxlIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvTWFrZWZpbGUKaW5kZXggY2IzZjkwODRhMjFi Li4zZDNkMmIzNTIzMDQgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L01ha2VmaWxl CisrKyBiL2RyaXZlcnMvbmV0L2V0aGVybmV0L01ha2VmaWxlCkBAIC0xOSw2ICsxOSw3IEBAIG9i ai0kKENPTkZJR19ORVRfWEdFTkUpICs9IGFwbS8KIG9iai0kKENPTkZJR19ORVRfVkVORE9SX0FQ UExFKSArPSBhcHBsZS8KIG9iai0kKENPTkZJR19ORVRfVkVORE9SX0FRVUFOVElBKSArPSBhcXVh bnRpYS8KIG9iai0kKENPTkZJR19ORVRfVkVORE9SX0FSQykgKz0gYXJjLworb2JqLSQoQ09ORklH X05FVF9WRU5ET1JfQVNJWCkgKz0gYXNpeC8KIG9iai0kKENPTkZJR19ORVRfVkVORE9SX0FUSEVS T1MpICs9IGF0aGVyb3MvCiBvYmotJChDT05GSUdfTkVUX1ZFTkRPUl9DQURFTkNFKSArPSBjYWRl bmNlLwogb2JqLSQoQ09ORklHX05FVF9WRU5ET1JfQlJPQURDT00pICs9IGJyb2FkY29tLwpkaWZm IC0tZ2l0IGEvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9LY29uZmlnIGIvZHJpdmVycy9uZXQv ZXRoZXJuZXQvYXNpeC9LY29uZmlnCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAw MDAwMC4uZWVkMDI0NTMzMTRjCi0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9uZXQvZXRoZXJu ZXQvYXNpeC9LY29uZmlnCkBAIC0wLDAgKzEsMzUgQEAKKyMKKyMgQXNpeCBuZXR3b3JrIGRldmlj ZSBjb25maWd1cmF0aW9uCisjCisKK2NvbmZpZyBORVRfVkVORE9SX0FTSVgKKwlib29sICJBc2l4 IGRldmljZXMiCisJZGVmYXVsdCB5CisJaGVscAorCSAgSWYgeW91IGhhdmUgYSBuZXR3b3JrIChF dGhlcm5ldCwgbm9uLVVTQiwgbm90IE5FMjAwMCBjb21wYXRpYmxlKQorCSAgaW50ZXJmYWNlIGJh c2VkIG9uIGEgY2hpcCBmcm9tIEFTSVgsIHNheSBZLgorCitpZiBORVRfVkVORE9SX0FTSVgKKwor Y29uZmlnIFNQSV9BWDg4Nzk2QworCXRyaXN0YXRlICJBc2l4IEFYODg3OTZDLVNQSSBzdXBwb3J0 IgorCXNlbGVjdCBQSFlMSUIKKwlkZXBlbmRzIG9uIFNQSQorCWRlcGVuZHMgb24gR1BJT0xJQgor CWhlbHAKKwkgIFNheSBZIGhlcmUgaWYgeW91IGludGVuZCB0byB1c2UgQVNJWCBBWDg4Nzk2QyBh dHRhY2hlZCBpbiBTUEkgbW9kZS4KKworY29uZmlnIFNQSV9BWDg4Nzk2Q19DT01QUkVTU0lPTgor CWJvb2wgIlNQSSB0cmFuc2ZlciBjb21wcmVzc2lvbiIKKwlkZWZhdWx0IG4KKwlkZXBlbmRzIG9u IFNQSV9BWDg4Nzk2QworCWhlbHAKKwkgIFNheSBZIGhlcmUgdG8gZW5hYmxlIFNQSSB0cmFuc2Zl ciBjb21wcmVzc2lvbi4gSXQgc2F2ZXMgdXAKKwkgIHRvIDI0IGR1bW15IGN5Y2xlcyBkdXJpbmcg ZWFjaCB0cmFuc2ZlciB3aGljaCBtYXkgbm90aWNlYWJseQorCSAgc3BlZWQgdXAgc2hvcnQgdHJh bnNmZXJzLiBUaGlzIHNldHMgdGhlIGRlZmF1bHQgdmFsdWUgdGhhdCBpcworCSAgaW5oZXJpdGVk IGJ5IG5ldHdvcmsgaW50ZXJmYWNlcyBkdXJpbmcgcHJvYmUuIEl0IGNhbiBiZQorCSAgY2hhbmdl ZCBhdCBydW4gdGltZSB2aWEgc3BpLWNvbXByZXNzaW9uIGV0aHRvb2wgdHVuYWJsZS4KKworCSAg SWYgdW5zdXJlIHNheSBOLgorCitlbmRpZiAjIE5FVF9WRU5ET1JfQVNJWApkaWZmIC0tZ2l0IGEv ZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9NYWtlZmlsZSBiL2RyaXZlcnMvbmV0L2V0aGVybmV0 L2FzaXgvTWFrZWZpbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4w YmZiYmIwNDI2MzQKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4 L01ha2VmaWxlCkBAIC0wLDAgKzEsNiBAQAorIworIyBNYWtlZmlsZSBmb3IgdGhlIEFzaXggbmV0 d29yayBkZXZpY2UgZHJpdmVycy4KKyMKKworb2JqLSQoQ09ORklHX1NQSV9BWDg4Nzk2QykgKz0g YXg4ODc5NmMubworYXg4ODc5NmMteSA6PSBheDg4Nzk2Y19tYWluLm8gYXg4ODc5NmNfaW9jdGwu byBheDg4Nzk2Y19zcGkubwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9h eDg4Nzk2Y19pb2N0bC5jIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19pb2N0 bC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uOTE2YWUzODBhMDA0 Ci0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19p b2N0bC5jCkBAIC0wLDAgKzEsMjM5IEBACisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BM LTIuMC1vbmx5CisvKgorICogQ29weXJpZ2h0IChjKSAyMDEwIEFTSVggRWxlY3Ryb25pY3MgQ29y cG9yYXRpb24KKyAqIENvcHlyaWdodCAoYykgMjAyMCBTYW1zdW5nIEVsZWN0cm9uaWNzIENvLiwg THRkLgorICoKKyAqIEFTSVggQVg4ODc5NkMgU1BJIEZhc3QgRXRoZXJuZXQgTGludXggZHJpdmVy CisgKi8KKworI2RlZmluZSBwcl9mbXQoZm10KQkiYXg4ODc5NmM6ICIgZm10CisKKyNpbmNsdWRl IDxsaW51eC9iaXRtYXAuaD4KKyNpbmNsdWRlIDxsaW51eC9pb3BvbGwuaD4KKyNpbmNsdWRlIDxs aW51eC9waHkuaD4KKyNpbmNsdWRlIDxsaW51eC9uZXRkZXZpY2UuaD4KKworI2luY2x1ZGUgImF4 ODg3OTZjX21haW4uaCIKKyNpbmNsdWRlICJheDg4Nzk2Y19pb2N0bC5oIgorCitzdGF0aWMgY29u c3QgY2hhciBheDg4Nzk2Y19wcml2X2ZsYWdfbmFtZXNbXVtFVEhfR1NUUklOR19MRU5dID0gewor CSJTUElDb21wcmVzc2lvbiIsCit9OworCitzdGF0aWMgdm9pZAorYXg4ODc5NmNfZ2V0X2Rydmlu Zm8oc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYsIHN0cnVjdCBldGh0b29sX2RydmluZm8gKmluZm8p Cit7CisJLyogSW5oZXJpdCBzdGFuZGFyZCBkZXZpY2UgaW5mbyAqLworCXN0cm5jcHkoaW5mby0+ ZHJpdmVyLCBEUlZfTkFNRSwgc2l6ZW9mKGluZm8tPmRyaXZlcikpOworfQorCitzdGF0aWMgdTMy IGF4ODg3OTZjX2dldF9tc2dsZXZlbChzdHJ1Y3QgbmV0X2RldmljZSAqbmRldikKK3sKKwlzdHJ1 Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2KTsK KworCXJldHVybiBheF9sb2NhbC0+bXNnX2VuYWJsZTsKK30KKworc3RhdGljIHZvaWQgYXg4ODc5 NmNfc2V0X21zZ2xldmVsKHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2LCB1MzIgbGV2ZWwpCit7CisJ c3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4Nzk2Y19kZXZpY2UobmRl dik7CisKKwlheF9sb2NhbC0+bXNnX2VuYWJsZSA9IGxldmVsOworfQorCitzdGF0aWMgdm9pZAor YXg4ODc5NmNfZ2V0X3BhdXNlcGFyYW0oc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYsIHN0cnVjdCBl dGh0b29sX3BhdXNlcGFyYW0gKnBhdXNlKQoreworCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4 X2xvY2FsID0gdG9fYXg4ODc5NmNfZGV2aWNlKG5kZXYpOworCisJcGF1c2UtPnR4X3BhdXNlID0g ISEoYXhfbG9jYWwtPmZsb3djdHJsICYgQVhfRkNfVFgpOworCXBhdXNlLT5yeF9wYXVzZSA9ICEh KGF4X2xvY2FsLT5mbG93Y3RybCAmIEFYX0ZDX1JYKTsKKwlwYXVzZS0+YXV0b25lZyA9IChheF9s b2NhbC0+Zmxvd2N0cmwgJiBBWF9GQ19BTkVHKSA/CisJCUFVVE9ORUdfRU5BQkxFIDoKKwkJQVVU T05FR19ESVNBQkxFOworfQorCitzdGF0aWMgaW50CitheDg4Nzk2Y19zZXRfcGF1c2VwYXJhbShz dHJ1Y3QgbmV0X2RldmljZSAqbmRldiwgc3RydWN0IGV0aHRvb2xfcGF1c2VwYXJhbSAqcGF1c2Up Cit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4Nzk2Y19kZXZp Y2UobmRldik7CisJaW50IGZjOworCisJLyogVGhlIGZvbGxvd2luZyBsb2dpYyBjb21lcyBmcm9t IHBoeWxpbmtfZXRodG9vbF9zZXRfcGF1c2VwYXJhbSgpICovCisJZmMgPSBwYXVzZS0+dHhfcGF1 c2UgPyBBWF9GQ19UWCA6IDA7CisJZmMgfD0gcGF1c2UtPnJ4X3BhdXNlID8gQVhfRkNfUlggOiAw OworCWZjIHw9IHBhdXNlLT5hdXRvbmVnID8gQVhfRkNfQU5FRyA6IDA7CisKKwlheF9sb2NhbC0+ Zmxvd2N0cmwgPSBmYzsKKworCWlmIChwYXVzZS0+YXV0b25lZykgeworCQlwaHlfc2V0X2FzeW1f cGF1c2UoYXhfbG9jYWwtPnBoeWRldiwgcGF1c2UtPnR4X3BhdXNlLAorCQkJCSAgIHBhdXNlLT5y eF9wYXVzZSk7CisJfSBlbHNlIHsKKwkJaW50IG1hY2NyID0gMDsKKworCQlwaHlfc2V0X2FzeW1f cGF1c2UoYXhfbG9jYWwtPnBoeWRldiwgMCwgMCk7CisJCW1hY2NyIHw9IChheF9sb2NhbC0+Zmxv d2N0cmwgJiBBWF9GQ19SWCkgPyBNQUNDUl9SWEZDX0VOQUJMRSA6IDA7CisJCW1hY2NyIHw9IChh eF9sb2NhbC0+Zmxvd2N0cmwgJiBBWF9GQ19UWCkgPyBNQUNDUl9UWEZDX0VOQUJMRSA6IDA7CisK KwkJbXV0ZXhfbG9jaygmYXhfbG9jYWwtPnNwaV9sb2NrKTsKKworCQltYWNjciB8PSBBWF9SRUFE KCZheF9sb2NhbC0+YXhfc3BpLCBQMF9NQUNDUikgJgorCQkJfihNQUNDUl9UWEZDX0VOQUJMRSB8 IE1BQ0NSX1JYRkNfRU5BQkxFKTsKKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIG1hY2Ny LCBQMF9NQUNDUik7CisKKwkJbXV0ZXhfdW5sb2NrKCZheF9sb2NhbC0+c3BpX2xvY2spOworCX0K KworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGF4ODg3OTZjX2dldF9yZWdzX2xlbihzdHJ1 Y3QgbmV0X2RldmljZSAqbmRldikKK3sKKwlyZXR1cm4gQVg4ODc5NkNfUkVHRFVNUF9MRU4gKyBB WDg4Nzk2Q19QSFlfUkVHRFVNUF9MRU47Cit9CisKK3N0YXRpYyB2b2lkCitheDg4Nzk2Y19nZXRf cmVncyhzdHJ1Y3QgbmV0X2RldmljZSAqbmRldiwgc3RydWN0IGV0aHRvb2xfcmVncyAqcmVncywg dm9pZCAqX3ApCit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4 Nzk2Y19kZXZpY2UobmRldik7CisJaW50IG9mZnNldCwgaTsKKwl1MTYgKnAgPSBfcDsKKworCW1l bXNldChwLCAwLCBheDg4Nzk2Y19nZXRfcmVnc19sZW4obmRldikpOworCisJbXV0ZXhfbG9jaygm YXhfbG9jYWwtPnNwaV9sb2NrKTsKKworCWZvciAob2Zmc2V0ID0gMDsgb2Zmc2V0IDwgQVg4ODc5 NkNfUkVHRFVNUF9MRU47IG9mZnNldCArPSAyKSB7CisJCWlmICghdGVzdF9iaXQob2Zmc2V0IC8g MiwgYXg4ODc5NmNfbm9fcmVnc19tYXNrKSkKKwkJCSpwID0gQVhfUkVBRCgmYXhfbG9jYWwtPmF4 X3NwaSwgb2Zmc2V0KTsKKwkJcCsrOworCX0KKworCW11dGV4X3VubG9jaygmYXhfbG9jYWwtPnNw aV9sb2NrKTsKKworCWZvciAoaSA9IDA7IGkgPCBBWDg4Nzk2Q19QSFlfUkVHRFVNUF9MRU4gLyAy OyBpKyspIHsKKwkJKnAgPSBwaHlfcmVhZChheF9sb2NhbC0+cGh5ZGV2LCBpKTsKKwkJcCsrOwor CX0KK30KKworc3RhdGljIHZvaWQKK2F4ODg3OTZjX2dldF9zdHJpbmdzKHN0cnVjdCBuZXRfZGV2 aWNlICpuZGV2LCB1MzIgc3RyaW5nc2V0LCB1OCAqZGF0YSkKK3sKKwlzd2l0Y2ggKHN0cmluZ3Nl dCkgeworCWNhc2UgRVRIX1NTX1BSSVZfRkxBR1M6CisJCW1lbWNweShkYXRhLCBheDg4Nzk2Y19w cml2X2ZsYWdfbmFtZXMsCisJCSAgICAgICBzaXplb2YoYXg4ODc5NmNfcHJpdl9mbGFnX25hbWVz KSk7CisJCWJyZWFrOworCX0KK30KKworc3RhdGljIGludAorYXg4ODc5NmNfZ2V0X3NzZXRfY291 bnQoc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYsIGludCBzdHJpbmdzZXQpCit7CisJaW50IHJldCA9 IDA7CisKKwlzd2l0Y2ggKHN0cmluZ3NldCkgeworCWNhc2UgRVRIX1NTX1BSSVZfRkxBR1M6CisJ CXJldCA9IEFSUkFZX1NJWkUoYXg4ODc5NmNfcHJpdl9mbGFnX25hbWVzKTsKKwkJYnJlYWs7CisJ ZGVmYXVsdDoKKwkJcmV0ID0gLUVPUE5PVFNVUFA7CisJfQorCisJcmV0dXJuIHJldDsKK30KKwor c3RhdGljIGludCBheDg4Nzk2Y19zZXRfcHJpdl9mbGFncyhzdHJ1Y3QgbmV0X2RldmljZSAqbmRl diwgdTMyIGZsYWdzKQoreworCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9f YXg4ODc5NmNfZGV2aWNlKG5kZXYpOworCisJaWYgKGZsYWdzICYgfkFYX1BSSVZfRkxBR1NfTUFT SykKKwkJcmV0dXJuIC1FT1BOT1RTVVBQOworCisJaWYgKChheF9sb2NhbC0+cHJpdl9mbGFncyBe IGZsYWdzKSAmIEFYX0NBUF9DT01QKQorCQlpZiAobmV0aWZfcnVubmluZyhuZGV2KSkKKwkJCXJl dHVybiAtRUJVU1k7CisKKwlheF9sb2NhbC0+cHJpdl9mbGFncyA9IGZsYWdzOworCisJcmV0dXJu IDA7Cit9CisKK3N0YXRpYyB1MzIgYXg4ODc5NmNfZ2V0X3ByaXZfZmxhZ3Moc3RydWN0IG5ldF9k ZXZpY2UgKm5kZXYpCit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0b19h eDg4Nzk2Y19kZXZpY2UobmRldik7CisKKwlyZXR1cm4gYXhfbG9jYWwtPnByaXZfZmxhZ3M7Cit9 CisKK2ludCBheDg4Nzk2Y19tZGlvX3JlYWQoc3RydWN0IG1paV9idXMgKm1kaW9idXMsIGludCBw aHlfaWQsIGludCBsb2MpCit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSBt ZGlvYnVzLT5wcml2OworCWludCByZXQ7CisKKwltdXRleF9sb2NrKCZheF9sb2NhbC0+c3BpX2xv Y2spOworCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBNRElPQ1JfUkFERFIobG9jKQorCQkJ fCBNRElPQ1JfRkFERFIocGh5X2lkKSB8IE1ESU9DUl9SRUFELCBQMl9NRElPQ1IpOworCisJcmV0 ID0gcmVhZF9wb2xsX3RpbWVvdXQoQVhfUkVBRCwgcmV0LAorCQkJCShyZXQgIT0gMCksCisJCQkJ MCwgamlmZmllc190b191c2VjcyhIWiAvIDEwMCksIGZhbHNlLAorCQkJCSZheF9sb2NhbC0+YXhf c3BpLCBQMl9NRElPQ1IpOworCWlmICghcmV0KQorCQlyZXQgPSBBWF9SRUFEKCZheF9sb2NhbC0+ YXhfc3BpLCBQMl9NRElPRFIpOworCisJbXV0ZXhfdW5sb2NrKCZheF9sb2NhbC0+c3BpX2xvY2sp OworCisJcmV0dXJuIHJldDsKK30KKworaW50CitheDg4Nzk2Y19tZGlvX3dyaXRlKHN0cnVjdCBt aWlfYnVzICptZGlvYnVzLCBpbnQgcGh5X2lkLCBpbnQgbG9jLCB1MTYgdmFsKQoreworCXN0cnVj dCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gbWRpb2J1cy0+cHJpdjsKKwlpbnQgcmV0Owor CisJbXV0ZXhfbG9jaygmYXhfbG9jYWwtPnNwaV9sb2NrKTsKKwlBWF9XUklURSgmYXhfbG9jYWwt PmF4X3NwaSwgdmFsLCBQMl9NRElPRFIpOworCisJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGks CisJCSBNRElPQ1JfUkFERFIobG9jKSB8IE1ESU9DUl9GQUREUihwaHlfaWQpCisJCSB8IE1ESU9D Ul9XUklURSwgUDJfTURJT0NSKTsKKworCXJldCA9IHJlYWRfcG9sbF90aW1lb3V0KEFYX1JFQUQs IHJldCwKKwkJCQkoKHJldCAmIE1ESU9DUl9WQUxJRCkgIT0gMCksIDAsCisJCQkJamlmZmllc190 b191c2VjcyhIWiAvIDEwMCksIGZhbHNlLAorCQkJCSZheF9sb2NhbC0+YXhfc3BpLCBQMl9NRElP Q1IpOworCW11dGV4X3VubG9jaygmYXhfbG9jYWwtPnNwaV9sb2NrKTsKKworCXJldHVybiByZXQ7 Cit9CisKK2NvbnN0IHN0cnVjdCBldGh0b29sX29wcyBheDg4Nzk2Y19ldGh0b29sX29wcyA9IHsK KwkuZ2V0X2RydmluZm8JCT0gYXg4ODc5NmNfZ2V0X2RydmluZm8sCisJLmdldF9saW5rCQk9IGV0 aHRvb2xfb3BfZ2V0X2xpbmssCisJLmdldF9tc2dsZXZlbAkJPSBheDg4Nzk2Y19nZXRfbXNnbGV2 ZWwsCisJLnNldF9tc2dsZXZlbAkJPSBheDg4Nzk2Y19zZXRfbXNnbGV2ZWwsCisJLmdldF9saW5r X2tzZXR0aW5ncwk9IHBoeV9ldGh0b29sX2dldF9saW5rX2tzZXR0aW5ncywKKwkuc2V0X2xpbmtf a3NldHRpbmdzCT0gcGh5X2V0aHRvb2xfc2V0X2xpbmtfa3NldHRpbmdzLAorCS5ud2F5X3Jlc2V0 CQk9IHBoeV9ldGh0b29sX253YXlfcmVzZXQsCisJLmdldF9wYXVzZXBhcmFtCQk9IGF4ODg3OTZj X2dldF9wYXVzZXBhcmFtLAorCS5zZXRfcGF1c2VwYXJhbQkJPSBheDg4Nzk2Y19zZXRfcGF1c2Vw YXJhbSwKKwkuZ2V0X3JlZ3NfbGVuCQk9IGF4ODg3OTZjX2dldF9yZWdzX2xlbiwKKwkuZ2V0X3Jl Z3MJCT0gYXg4ODc5NmNfZ2V0X3JlZ3MsCisJLmdldF9zdHJpbmdzCQk9IGF4ODg3OTZjX2dldF9z dHJpbmdzLAorCS5nZXRfc3NldF9jb3VudAkJPSBheDg4Nzk2Y19nZXRfc3NldF9jb3VudCwKKwku Z2V0X3ByaXZfZmxhZ3MJCT0gYXg4ODc5NmNfZ2V0X3ByaXZfZmxhZ3MsCisJLnNldF9wcml2X2Zs YWdzCQk9IGF4ODg3OTZjX3NldF9wcml2X2ZsYWdzLAorfTsKKworaW50IGF4ODg3OTZjX2lvY3Rs KHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2LCBzdHJ1Y3QgaWZyZXEgKmlmciwgaW50IGNtZCkKK3sK KwlpbnQgcmV0OworCisJcmV0ID0gcGh5X21paV9pb2N0bChuZGV2LT5waHlkZXYsIGlmciwgY21k KTsKKworCXJldHVybiByZXQ7Cit9CmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC9ldGhlcm5ldC9h c2l4L2F4ODg3OTZjX2lvY3RsLmggYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZj X2lvY3RsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4zNGQyYTdk Y2M1ZWYKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3 OTZjX2lvY3RsLmgKQEAgLTAsMCArMSwyNiBAQAorLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6 IEdQTC0yLjAtb25seSAqLworLyoKKyAqIENvcHlyaWdodCAoYykgMjAxMCBBU0lYIEVsZWN0cm9u aWNzIENvcnBvcmF0aW9uCisgKiBDb3B5cmlnaHQgKGMpIDIwMjAgU2Ftc3VuZyBFbGVjdHJvbmlj cyBDby4sIEx0ZC4KKyAqCisgKiBBU0lYIEFYODg3OTZDIFNQSSBGYXN0IEV0aGVybmV0IExpbnV4 IGRyaXZlcgorICovCisKKyNpZm5kZWYgX0FYODg3OTZDX0lPQ1RMX0gKKyNkZWZpbmUgX0FYODg3 OTZDX0lPQ1RMX0gKKworI2luY2x1ZGUgPGxpbnV4L2V0aHRvb2wuaD4KKyNpbmNsdWRlIDxsaW51 eC9uZXRkZXZpY2UuaD4KKworI2luY2x1ZGUgImF4ODg3OTZjX21haW4uaCIKKworZXh0ZXJuIGNv bnN0IHN0cnVjdCBldGh0b29sX29wcyBheDg4Nzk2Y19ldGh0b29sX29wczsKKworYm9vbCBheDg4 Nzk2Y19jaGVja19wb3dlcihjb25zdCBzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCk7 Citib29sIGF4ODg3OTZjX2NoZWNrX3Bvd2VyX2FuZF93YWtlKHN0cnVjdCBheDg4Nzk2Y19kZXZp Y2UgKmF4X2xvY2FsKTsKK3ZvaWQgYXg4ODc5NmNfc2V0X3Bvd2VyX3NhdmluZyhzdHJ1Y3QgYXg4 ODc5NmNfZGV2aWNlICpheF9sb2NhbCwgdTggcHNfbGV2ZWwpOworaW50IGF4ODg3OTZjX21kaW9f cmVhZChzdHJ1Y3QgbWlpX2J1cyAqbWRpb2J1cywgaW50IHBoeV9pZCwgaW50IGxvYyk7CitpbnQg YXg4ODc5NmNfbWRpb193cml0ZShzdHJ1Y3QgbWlpX2J1cyAqbWRpb2J1cywgaW50IHBoeV9pZCwg aW50IGxvYywgdTE2IHZhbCk7CitpbnQgYXg4ODc5NmNfaW9jdGwoc3RydWN0IG5ldF9kZXZpY2Ug KmRldiwgc3RydWN0IGlmcmVxICppZnIsIGludCBjbWQpOworCisjZW5kaWYKZGlmZiAtLWdpdCBh L2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfbWFpbi5jIGIvZHJpdmVycy9uZXQv ZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19tYWluLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXgg MDAwMDAwMDAwMDAwLi40ZGNhMmU3NjAxMDUKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL25l dC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX21haW4uYwpAQCAtMCwwICsxLDExNDYgQEAKKy8vIFNQ RFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkKKy8qCisgKiBDb3B5cmlnaHQgKGMp IDIwMTAgQVNJWCBFbGVjdHJvbmljcyBDb3Jwb3JhdGlvbgorICogQ29weXJpZ2h0IChjKSAyMDIw IFNhbXN1bmcgRWxlY3Ryb25pY3MgQ28uLCBMdGQuCisgKgorICogQVNJWCBBWDg4Nzk2QyBTUEkg RmFzdCBFdGhlcm5ldCBMaW51eCBkcml2ZXIKKyAqLworCisjZGVmaW5lIHByX2ZtdChmbXQpCSJh eDg4Nzk2YzogIiBmbXQKKworI2luY2x1ZGUgImF4ODg3OTZjX21haW4uaCIKKyNpbmNsdWRlICJh eDg4Nzk2Y19pb2N0bC5oIgorCisjaW5jbHVkZSA8bGludXgvYml0bWFwLmg+CisjaW5jbHVkZSA8 bGludXgvZXRoZXJkZXZpY2UuaD4KKyNpbmNsdWRlIDxsaW51eC9pb3BvbGwuaD4KKyNpbmNsdWRl IDxsaW51eC9sb2NrZGVwLmg+CisjaW5jbHVkZSA8bGludXgvbWRpby5oPgorI2luY2x1ZGUgPGxp bnV4L21pbm1heC5oPgorI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgorI2luY2x1ZGUgPGxpbnV4 L25ldGRldmljZS5oPgorI2luY2x1ZGUgPGxpbnV4L29mLmg+CisjaW5jbHVkZSA8bGludXgvcGh5 Lmg+CisjaW5jbHVkZSA8bGludXgvc2tidWZmLmg+CisjaW5jbHVkZSA8bGludXgvc3BpL3NwaS5o PgorCitzdGF0aWMgaW50IGNvbXAgPSBJU19FTkFCTEVEKENPTkZJR19TUElfQVg4ODc5NkNfQ09N UFJFU1NJT04pOworc3RhdGljIGludCBtc2dfZW5hYmxlID0gTkVUSUZfTVNHX1BST0JFIHwKKwkJ CU5FVElGX01TR19MSU5LIHwKKwkJCU5FVElGX01TR19SWF9FUlIgfAorCQkJTkVUSUZfTVNHX1RY X0VSUjsKKworc3RhdGljIGNoYXIgKm5vX3JlZ3NfbGlzdCA9ICI4MDAxODAwMSxlMTkxODAwMSw4 MDAxYTAwMSxmYzBkMDAwMCI7Cit1bnNpZ25lZCBsb25nIGF4ODg3OTZjX25vX3JlZ3NfbWFza1tB WDg4Nzk2Q19SRUdEVU1QX0xFTiAvIChzaXplb2YodW5zaWduZWQgbG9uZykgKiA4KV07CisKK21v ZHVsZV9wYXJhbShtc2dfZW5hYmxlLCBpbnQsIDA0NDQpOworTU9EVUxFX1BBUk1fREVTQyhtc2df ZW5hYmxlLCAiTWVzc2FnZSBtYXNrIChzZWUgbGludXgvbmV0ZGV2aWNlLmggZm9yIGJpdG1hcCki KTsKKworc3RhdGljIGludCBheDg4Nzk2Y19zb2Z0X3Jlc2V0KHN0cnVjdCBheDg4Nzk2Y19kZXZp Y2UgKmF4X2xvY2FsKQoreworCXUxNiB0ZW1wOworCWludCByZXQ7CisKKwlsb2NrZGVwX2Fzc2Vy dF9oZWxkKCZheF9sb2NhbC0+c3BpX2xvY2spOworCisJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9z cGksIFBTUl9SRVNFVCwgUDBfUFNSKTsKKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgUFNS X1JFU0VUX0NMUiwgUDBfUFNSKTsKKworCXJldCA9IHJlYWRfcG9sbF90aW1lb3V0KEFYX1JFQUQs IHJldCwKKwkJCQkocmV0ICYgUFNSX0RFVl9SRUFEWSksCisJCQkJMCwgamlmZmllc190b191c2Vj cygxNjAgKiBIWiAvIDEwMDApLCBmYWxzZSwKKwkJCQkmYXhfbG9jYWwtPmF4X3NwaSwgUDBfUFNS KTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCisJdGVtcCA9IEFYX1JFQUQoJmF4X2xvY2Fs LT5heF9zcGksIFA0X1NQSUNSKTsKKwlpZiAoYXhfbG9jYWwtPnByaXZfZmxhZ3MgJiBBWF9DQVBf Q09NUCkgeworCQlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwKKwkJCSAodGVtcCB8IFNQSUNS X1JDRU4gfCBTUElDUl9RQ0VOKSwgUDRfU1BJQ1IpOworCQlheF9sb2NhbC0+YXhfc3BpLmNvbXAg PSAxOworCX0gZWxzZSB7CisJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLAorCQkJICh0ZW1w ICYgfihTUElDUl9SQ0VOIHwgU1BJQ1JfUUNFTikpLCBQNF9TUElDUik7CisJCWF4X2xvY2FsLT5h eF9zcGkuY29tcCA9IDA7CisJfQorCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgYXg4ODc5 NmNfcmVsb2FkX2VlcHJvbShzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCkKK3sKKwlp bnQgcmV0OworCisJbG9ja2RlcF9hc3NlcnRfaGVsZCgmYXhfbG9jYWwtPnNwaV9sb2NrKTsKKwor CUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBFRUNSX1JFTE9BRCwgUDNfRUVDUik7CisKKwly ZXQgPSByZWFkX3BvbGxfdGltZW91dChBWF9SRUFELCByZXQsCisJCQkJKHJldCAmIFBTUl9ERVZf UkVBRFkpLAorCQkJCTAsIGppZmZpZXNfdG9fdXNlY3MoMiAqIEhaIC8gMTAwMCksIGZhbHNlLAor CQkJCSZheF9sb2NhbC0+YXhfc3BpLCBQMF9QU1IpOworCWlmIChyZXQpIHsKKwkJZGV2X2Vycigm YXhfbG9jYWwtPnNwaS0+ZGV2LAorCQkJInRpbWVvdXQgd2FpdGluZyBmb3IgcmVsb2FkIGVlcHJv bVxuIik7CisJCXJldHVybiByZXQ7CisJfQorCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lk IGF4ODg3OTZjX3NldF9od19tdWx0aWNhc3Qoc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYpCit7CisJ c3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4Nzk2Y19kZXZpY2UobmRl dik7CisJaW50IG1jX2NvdW50ID0gbmV0ZGV2X21jX2NvdW50KG5kZXYpOworCXUxNiByeF9jdGwg PSBSWENSX0FCOworCisJbG9ja2RlcF9hc3NlcnRfaGVsZCgmYXhfbG9jYWwtPnNwaV9sb2NrKTsK KworCW1lbXNldChheF9sb2NhbC0+bXVsdGlfZmlsdGVyLCAwLCBBWF9NQ0FTVF9GSUxURVJfU0la RSk7CisKKwlpZiAobmRldi0+ZmxhZ3MgJiBJRkZfUFJPTUlTQykgeworCQlyeF9jdGwgfD0gUlhD Ul9QUk87CisKKwl9IGVsc2UgaWYgKG5kZXYtPmZsYWdzICYgSUZGX0FMTE1VTFRJIHx8IG1jX2Nv dW50ID4gQVhfTUFYX01DQVNUKSB7CisJCXJ4X2N0bCB8PSBSWENSX0FNQUxMOworCisJfSBlbHNl IGlmIChtY19jb3VudCA9PSAwKSB7CisJCS8qIGp1c3QgYnJvYWRjYXN0IGFuZCBkaXJlY3RlZCAq LworCX0gZWxzZSB7CisJCXUzMiBjcmNfYml0czsKKwkJaW50IGk7CisJCXN0cnVjdCBuZXRkZXZf aHdfYWRkciAqaGE7CisKKwkJbmV0ZGV2X2Zvcl9lYWNoX21jX2FkZHIoaGEsIG5kZXYpIHsKKwkJ CWNyY19iaXRzID0gZXRoZXJfY3JjKEVUSF9BTEVOLCBoYS0+YWRkcik7CisJCQlheF9sb2NhbC0+ bXVsdGlfZmlsdGVyW2NyY19iaXRzID4+IDI5XSB8PQorCQkJCQkJKDEgPDwgKChjcmNfYml0cyA+ PiAyNikgJiA3KSk7CisJCX0KKworCQlmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7CisJCQlBWF9X UklURSgmYXhfbG9jYWwtPmF4X3NwaSwKKwkJCQkgKChheF9sb2NhbC0+bXVsdGlfZmlsdGVyW2kg KiAyICsgMV0gPDwgOCkgfAorCQkJCSAgYXhfbG9jYWwtPm11bHRpX2ZpbHRlcltpICogMl0pLCBQ M19NRkFSKGkpKTsKKwkJfQorCX0KKworCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCByeF9j dGwsIFAyX1JYQ1IpOworfQorCitzdGF0aWMgdm9pZCBheDg4Nzk2Y19zZXRfbWFjX2FkZHIoc3Ry dWN0IG5ldF9kZXZpY2UgKm5kZXYpCit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9j YWwgPSB0b19heDg4Nzk2Y19kZXZpY2UobmRldik7CisKKwlsb2NrZGVwX2Fzc2VydF9oZWxkKCZh eF9sb2NhbC0+c3BpX2xvY2spOworCisJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksICgodTE2 KShuZGV2LT5kZXZfYWRkcls0XSA8PCA4KSB8CisJCQkodTE2KW5kZXYtPmRldl9hZGRyWzVdKSwg UDNfTUFDQVNSMCk7CisJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksICgodTE2KShuZGV2LT5k ZXZfYWRkclsyXSA8PCA4KSB8CisJCQkodTE2KW5kZXYtPmRldl9hZGRyWzNdKSwgUDNfTUFDQVNS MSk7CisJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksICgodTE2KShuZGV2LT5kZXZfYWRkclsw XSA8PCA4KSB8CisJCQkodTE2KW5kZXYtPmRldl9hZGRyWzFdKSwgUDNfTUFDQVNSMik7Cit9CisK K3N0YXRpYyB2b2lkIGF4ODg3OTZjX2xvYWRfbWFjX2FkZHIoc3RydWN0IG5ldF9kZXZpY2UgKm5k ZXYpCit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4Nzk2Y19k ZXZpY2UobmRldik7CisJdTE2IHRlbXA7CisKKwlsb2NrZGVwX2Fzc2VydF9oZWxkKCZheF9sb2Nh bC0+c3BpX2xvY2spOworCisJLyogVHJ5IHRoZSBkZXZpY2UgdHJlZSBmaXJzdCAqLworCWlmICgh ZXRoX3BsYXRmb3JtX2dldF9tYWNfYWRkcmVzcygmYXhfbG9jYWwtPnNwaS0+ZGV2LCBuZGV2LT5k ZXZfYWRkcikgJiYKKwkgICAgaXNfdmFsaWRfZXRoZXJfYWRkcihuZGV2LT5kZXZfYWRkcikpIHsK KwkJaWYgKG5ldGlmX21zZ19wcm9iZShheF9sb2NhbCkpCisJCQlkZXZfaW5mbygmYXhfbG9jYWwt PnNwaS0+ZGV2LAorCQkJCSAiTUFDIGFkZHJlc3MgcmVhZCBmcm9tIGRldmljZSB0cmVlXG4iKTsK KwkJcmV0dXJuOworCX0KKworCS8qIFJlYWQgdGhlIE1BQyBhZGRyZXNzIGZyb20gQVg4ODc5NkMg Ki8KKwl0ZW1wID0gQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDNfTUFDQVNSMCk7CisJbmRl di0+ZGV2X2FkZHJbNV0gPSAodTgpdGVtcDsKKwluZGV2LT5kZXZfYWRkcls0XSA9ICh1OCkodGVt cCA+PiA4KTsKKworCXRlbXAgPSBBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQM19NQUNBU1Ix KTsKKwluZGV2LT5kZXZfYWRkclszXSA9ICh1OCl0ZW1wOworCW5kZXYtPmRldl9hZGRyWzJdID0g KHU4KSh0ZW1wID4+IDgpOworCisJdGVtcCA9IEFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAz X01BQ0FTUjIpOworCW5kZXYtPmRldl9hZGRyWzFdID0gKHU4KXRlbXA7CisJbmRldi0+ZGV2X2Fk ZHJbMF0gPSAodTgpKHRlbXAgPj4gOCk7CisKKwlpZiAoaXNfdmFsaWRfZXRoZXJfYWRkcihuZGV2 LT5kZXZfYWRkcikpIHsKKwkJaWYgKG5ldGlmX21zZ19wcm9iZShheF9sb2NhbCkpCisJCQlkZXZf aW5mbygmYXhfbG9jYWwtPnNwaS0+ZGV2LAorCQkJCSAiTUFDIGFkZHJlc3MgcmVhZCBmcm9tIEFT SVggY2hpcFxuIik7CisJCXJldHVybjsKKwl9CisKKwkvKiBVc2UgcmFuZG9tIGFkZHJlc3MgaWYg bm9uZSBmb3VuZCAqLworCWlmIChuZXRpZl9tc2dfcHJvYmUoYXhfbG9jYWwpKQorCQlkZXZfaW5m bygmYXhfbG9jYWwtPnNwaS0+ZGV2LCAiVXNlIHJhbmRvbSBNQUMgYWRkcmVzc1xuIik7CisJZXRo X2h3X2FkZHJfcmFuZG9tKG5kZXYpOworfQorCitzdGF0aWMgdm9pZCBheDg4Nzk2Y19wcm9jX3R4 X2hkcihzdHJ1Y3QgdHhfcGt0X2luZm8gKmluZm8sIHU4IGlwX3N1bW1lZCkKK3sKKwl1MTYgcGt0 X2xlbl9iYXIgPSAofmluZm8tPnBrdF9sZW4gJiBUWF9IRFJfU09QX1BLVExFTkJBUik7CisKKwkv KiBQcmVwYXJlIFNPUCBoZWFkZXIgKi8KKwlpbmZvLT5zb3AuZmxhZ3NfbGVuID0gaW5mby0+cGt0 X2xlbiB8CisJCSgoaXBfc3VtbWVkID09IENIRUNLU1VNX05PTkUpIHx8CisJCSAoaXBfc3VtbWVk ID09IENIRUNLU1VNX1VOTkVDRVNTQVJZKSA/IFRYX0hEUl9TT1BfRElDRiA6IDApOworCisJaW5m by0+c29wLnNlcV9sZW5iYXIgPSAoKGluZm8tPnNlcV9udW0gPDwgMTEpICYgVFhfSERSX1NPUF9T RVFOVU0pCisJCQkJfCBwa3RfbGVuX2JhcjsKKwljcHVfdG9fYmUxNnMoJmluZm8tPnNvcC5mbGFn c19sZW4pOworCWNwdV90b19iZTE2cygmaW5mby0+c29wLnNlcV9sZW5iYXIpOworCisJLyogUHJl cGFyZSBTZWdtZW50IGhlYWRlciAqLworCWluZm8tPnNlZy5mbGFnc19zZXFudW1fc2VnbGVuID0g VFhfSERSX1NFR19GUyB8IFRYX0hEUl9TRUdfTFMKKwkJCQkJCXwgaW5mby0+cGt0X2xlbjsKKwor CWluZm8tPnNlZy5lb19zb19zZWdsZW5iYXIgPSBwa3RfbGVuX2JhcjsKKworCWNwdV90b19iZTE2 cygmaW5mby0+c2VnLmZsYWdzX3NlcW51bV9zZWdsZW4pOworCWNwdV90b19iZTE2cygmaW5mby0+ c2VnLmVvX3NvX3NlZ2xlbmJhcik7CisKKwkvKiBQcmVwYXJlIEVPUCBoZWFkZXIgKi8KKwlpbmZv LT5lb3Auc2VxX2xlbiA9ICgoaW5mby0+c2VxX251bSA8PCAxMSkgJgorCQkJICAgICBUWF9IRFJf RU9QX1NFUU5VTSkgfCBpbmZvLT5wa3RfbGVuOworCWluZm8tPmVvcC5zZXFiYXJfbGVuYmFyID0g KCh+aW5mby0+c2VxX251bSA8PCAxMSkgJgorCQkJCSAgIFRYX0hEUl9FT1BfU0VRTlVNQkFSKSB8 IHBrdF9sZW5fYmFyOworCisJY3B1X3RvX2JlMTZzKCZpbmZvLT5lb3Auc2VxX2xlbik7CisJY3B1 X3RvX2JlMTZzKCZpbmZvLT5lb3Auc2VxYmFyX2xlbmJhcik7Cit9CisKK3N0YXRpYyBpbnQKK2F4 ODg3OTZjX2NoZWNrX2ZyZWVfcGFnZXMoc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWws IHU4IG5lZWRfcGFnZXMpCit7CisJdTggZnJlZV9wYWdlczsKKwl1MTYgdG1wOworCisJbG9ja2Rl cF9hc3NlcnRfaGVsZCgmYXhfbG9jYWwtPnNwaV9sb2NrKTsKKworCWZyZWVfcGFnZXMgPSBBWF9S RUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQMF9URkJGQ1IpICYgVFhfRlJFRUJVRl9NQVNLOworCWlm IChmcmVlX3BhZ2VzIDwgbmVlZF9wYWdlcykgeworCQkvKiBzY2hlZHVsZSBmcmVlIHBhZ2UgaW50 ZXJydXB0ICovCisJCXRtcCA9IEFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAwX1RGQkZDUikK KwkJCQkmIFRGQkZDUl9TQ0hFX0ZSRUVfUEFHRTsKKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9z cGksIHRtcCB8IFRGQkZDUl9UWF9QQUdFX1NFVCB8CisJCQkJVEZCRkNSX1NFVF9GUkVFX1BBR0Uo bmVlZF9wYWdlcyksCisJCQkJUDBfVEZCRkNSKTsKKwkJcmV0dXJuIC1FTk9NRU07CisJfQorCisJ cmV0dXJuIDA7Cit9CisKK3N0YXRpYyBzdHJ1Y3Qgc2tfYnVmZiAqCitheDg4Nzk2Y190eF9maXh1 cChzdHJ1Y3QgbmV0X2RldmljZSAqbmRldiwgc3RydWN0IHNrX2J1ZmZfaGVhZCAqcSkKK3sKKwlz dHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2 KTsKKwl1OCBzcGlfbGVuID0gYXhfbG9jYWwtPmF4X3NwaS5jb21wID8gMSA6IDQ7CisJc3RydWN0 IHNrX2J1ZmYgKnNrYjsKKwlzdHJ1Y3QgdHhfcGt0X2luZm8gaW5mbzsKKwlzdHJ1Y3Qgc2tiX2Rh dGEgKmVudHJ5OworCXUxNiBwa3RfbGVuOworCXU4IHBhZGxlbiwgc2VxX251bTsKKwl1OCBuZWVk X3BhZ2VzOworCWludCBoZWFkcm9vbTsKKwlpbnQgdGFpbHJvb207CisKKwlpZiAoc2tiX3F1ZXVl X2VtcHR5KHEpKQorCQlyZXR1cm4gTlVMTDsKKworCXNrYiA9IHNrYl9wZWVrKHEpOworCXBrdF9s ZW4gPSBza2ItPmxlbjsKKwluZWVkX3BhZ2VzID0gKHBrdF9sZW4gKyBUWF9PVkVSSEVBRCArIDEy NykgPj4gNzsKKwlpZiAoYXg4ODc5NmNfY2hlY2tfZnJlZV9wYWdlcyhheF9sb2NhbCwgbmVlZF9w YWdlcykgIT0gMCkKKwkJcmV0dXJuIE5VTEw7CisKKwloZWFkcm9vbSA9IHNrYl9oZWFkcm9vbShz a2IpOworCXRhaWxyb29tID0gc2tiX3RhaWxyb29tKHNrYik7CisJcGFkbGVuID0gcm91bmRfdXAo cGt0X2xlbiwgNCkgLSBwa3RfbGVuOworCXNlcV9udW0gPSArK2F4X2xvY2FsLT5zZXFfbnVtICYg MHgxRjsKKworCWluZm8ucGt0X2xlbiA9IHBrdF9sZW47CisKKwlpZiAoc2tiX2Nsb25lZChza2Ip IHx8CisJICAgIChoZWFkcm9vbSA8IChUWF9PVkVSSEVBRCArIHNwaV9sZW4pKSB8fAorCSAgICAo dGFpbHJvb20gPCAocGFkbGVuICsgVFhfRU9QX1NJWkUpKSkgeworCQlzaXplX3QgaCA9IG1heCgo VFhfT1ZFUkhFQUQgKyBzcGlfbGVuKSAtIGhlYWRyb29tLCAwKTsKKwkJc2l6ZV90IHQgPSBtYXgo KHBhZGxlbiArIFRYX0VPUF9TSVpFKSAtIHRhaWxyb29tLCAwKTsKKworCQlpZiAocHNrYl9leHBh bmRfaGVhZChza2IsIGgsIHQsIEdGUF9LRVJORUwpKQorCQkJcmV0dXJuIE5VTEw7CisJfQorCisJ aW5mby5zZXFfbnVtID0gc2VxX251bTsKKwlheDg4Nzk2Y19wcm9jX3R4X2hkcigmaW5mbywgc2ti LT5pcF9zdW1tZWQpOworCisJLyogU09QIGFuZCBTRUcgaGVhZGVyICovCisJbWVtY3B5KHNrYl9w dXNoKHNrYiwgVFhfT1ZFUkhFQUQpLCAmaW5mby5zb3AsIFRYX09WRVJIRUFEKTsKKworCS8qIFdy aXRlIFNQSSBUWFEgaGVhZGVyICovCisJbWVtY3B5KHNrYl9wdXNoKHNrYiwgc3BpX2xlbiksIGF4 ODg3OTZjX3R4X2NtZF9idWYsIHNwaV9sZW4pOworCisJLyogTWFrZSAzMi1iaXQgYWxpZ25tZW50 ICovCisJc2tiX3B1dChza2IsIHBhZGxlbik7CisKKwkvKiBFT1AgaGVhZGVyICovCisJbWVtY3B5 KHNrYl9wdXQoc2tiLCBUWF9FT1BfU0laRSksICZpbmZvLmVvcCwgVFhfRU9QX1NJWkUpOworCisJ c2tiX3VubGluayhza2IsIHEpOworCisJZW50cnkgPSAoc3RydWN0IHNrYl9kYXRhICopc2tiLT5j YjsKKwltZW1zZXQoZW50cnksIDAsIHNpemVvZigqZW50cnkpKTsKKwllbnRyeS0+bGVuID0gcGt0 X2xlbjsKKworCWlmIChuZXRpZl9tc2dfcGt0ZGF0YShheF9sb2NhbCkpIHsKKwkJY2hhciBwZnhb SUZOQU1TSVogKyA3XTsKKworCQlzbnByaW50ZihwZngsIHNpemVvZihwZngpLCAiJXM6ICAgICAi LCBuZGV2LT5uYW1lKTsKKworCQluZXRkZXZfaW5mbyhuZGV2LCAiVFggcGFja2V0IGxlbiAlZCwg dG90YWwgbGVuICVkLCBzZXEgJWRcbiIsCisJCQkgICAgcGt0X2xlbiwgc2tiLT5sZW4sIHNlcV9u dW0pOworCisJCW5ldGRldl9pbmZvKG5kZXYsICIgIFNQSSBIZWFkZXI6XG4iKTsKKwkJcHJpbnRf aGV4X2R1bXAoS0VSTl9JTkZPLCBwZngsIERVTVBfUFJFRklYX09GRlNFVCwgMTYsIDEsCisJCQkg ICAgICAgc2tiLT5kYXRhLCA0LCAwKTsKKworCQluZXRkZXZfaW5mbyhuZGV2LCAiICBUWCBTT1A6 XG4iKTsKKwkJcHJpbnRfaGV4X2R1bXAoS0VSTl9JTkZPLCBwZngsIERVTVBfUFJFRklYX09GRlNF VCwgMTYsIDEsCisJCQkgICAgICAgc2tiLT5kYXRhICsgNCwgVFhfT1ZFUkhFQUQsIDApOworCisJ CW5ldGRldl9pbmZvKG5kZXYsICIgIFRYIHBhY2tldDpcbiIpOworCQlwcmludF9oZXhfZHVtcChL RVJOX0lORk8sIHBmeCwgRFVNUF9QUkVGSVhfT0ZGU0VULCAxNiwgMSwKKwkJCSAgICAgICBza2It PmRhdGEgKyA0ICsgVFhfT1ZFUkhFQUQsCisJCQkgICAgICAgc2tiLT5sZW4gLSBUWF9FT1BfU0la RSAtIDQgLSBUWF9PVkVSSEVBRCwgMCk7CisKKwkJbmV0ZGV2X2luZm8obmRldiwgIiAgVFggRU9Q OlxuIik7CisJCXByaW50X2hleF9kdW1wKEtFUk5fSU5GTywgcGZ4LCBEVU1QX1BSRUZJWF9PRkZT RVQsIDE2LCAxLAorCQkJICAgICAgIHNrYi0+ZGF0YSArIHNrYi0+bGVuIC0gNCwgNCwgMCk7CisJ fQorCisJcmV0dXJuIHNrYjsKK30KKworc3RhdGljIGludCBheDg4Nzk2Y19oYXJkX3htaXQoc3Ry dWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwpCit7CisJc3RydWN0IGF4ODg3OTZjX3BjcHVf c3RhdHMgKnN0YXRzOworCXN0cnVjdCBza19idWZmICp0eF9za2I7CisJc3RydWN0IHNrYl9kYXRh ICplbnRyeTsKKworCWxvY2tkZXBfYXNzZXJ0X2hlbGQoJmF4X2xvY2FsLT5zcGlfbG9jayk7CisK KwlzdGF0cyA9IHRoaXNfY3B1X3B0cihheF9sb2NhbC0+c3RhdHMpOworCXR4X3NrYiA9IGF4ODg3 OTZjX3R4X2ZpeHVwKGF4X2xvY2FsLT5uZGV2LCAmYXhfbG9jYWwtPnR4X3dhaXRfcSk7CisKKwlp ZiAoIXR4X3NrYikgeworCQl0aGlzX2NwdV9pbmMoYXhfbG9jYWwtPnN0YXRzLT50eF9kcm9wcGVk KTsKKwkJcmV0dXJuIDA7CisJfQorCWVudHJ5ID0gKHN0cnVjdCBza2JfZGF0YSAqKXR4X3NrYi0+ Y2I7CisKKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwKKwkJIChUU05SX1RYQl9TVEFSVCB8 IFRTTlJfUEtUX0NOVCgxKSksIFAwX1RTTlIpOworCisJYXhzcGlfd3JpdGVfdHhxKCZheF9sb2Nh bC0+YXhfc3BpLCB0eF9za2ItPmRhdGEsIHR4X3NrYi0+bGVuKTsKKworCWlmICgoKEFYX1JFQUQo JmF4X2xvY2FsLT5heF9zcGksIFAwX1RTTlIpICYgVFhOUl9UWEJfSURMRSkgPT0gMCkgfHwKKwkg ICAgKChJU1JfVFhFUlIgJiBBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQMF9JU1IpKSAhPSAw KSkgeworCQkvKiBBY2sgdHggZXJyb3IgaW50ICovCisJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhf c3BpLCBJU1JfVFhFUlIsIFAwX0lTUik7CisKKwkJdGhpc19jcHVfaW5jKGF4X2xvY2FsLT5zdGF0 cy0+dHhfZHJvcHBlZCk7CisKKwkJaWYgKG5ldF9yYXRlbGltaXQoKSkKKwkJCW5ldGlmX2Vycihh eF9sb2NhbCwgdHhfZXJyLCBheF9sb2NhbC0+bmRldiwKKwkJCQkgICJUWCBGSUZPIGVycm9yLCBy ZS1pbml0aWFsaXplIHRoZSBUWCBicmlkZ2VcbiIpOworCisJCS8qIFJlaW5pdGlhbCB0eCBicmlk Z2UgKi8KKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIFRYTlJfVFhCX1JFSU5JVCB8CisJ CQlBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQMF9UU05SKSwgUDBfVFNOUik7CisJCWF4X2xv Y2FsLT5zZXFfbnVtID0gMDsKKwl9IGVsc2UgeworCQl1NjRfc3RhdHNfdXBkYXRlX2JlZ2luKCZz dGF0cy0+c3luY3ApOworCQl1NjRfc3RhdHNfaW5jKCZzdGF0cy0+dHhfcGFja2V0cyk7CisJCXU2 NF9zdGF0c19hZGQoJnN0YXRzLT50eF9ieXRlcywgZW50cnktPmxlbik7CisJCXU2NF9zdGF0c191 cGRhdGVfZW5kKCZzdGF0cy0+c3luY3ApOworCX0KKworCWVudHJ5LT5zdGF0ZSA9IHR4X2RvbmU7 CisJZGV2X2tmcmVlX3NrYih0eF9za2IpOworCisJcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQK K2F4ODg3OTZjX3N0YXJ0X3htaXQoc3RydWN0IHNrX2J1ZmYgKnNrYiwgc3RydWN0IG5ldF9kZXZp Y2UgKm5kZXYpCit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4 Nzk2Y19kZXZpY2UobmRldik7CisKKwlza2JfcXVldWVfdGFpbCgmYXhfbG9jYWwtPnR4X3dhaXRf cSwgc2tiKTsKKwlpZiAoc2tiX3F1ZXVlX2xlbigmYXhfbG9jYWwtPnR4X3dhaXRfcSkgPiBUWF9R VUVVRV9ISUdIX1dBVEVSKQorCQluZXRpZl9zdG9wX3F1ZXVlKG5kZXYpOworCisJc2V0X2JpdChF VkVOVF9UWCwgJmF4X2xvY2FsLT5mbGFncyk7CisJc2NoZWR1bGVfd29yaygmYXhfbG9jYWwtPmF4 X3dvcmspOworCisJcmV0dXJuIE5FVERFVl9UWF9PSzsKK30KKworc3RhdGljIHZvaWQKK2F4ODg3 OTZjX3NrYl9yZXR1cm4oc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwsCisJCSAgICBz dHJ1Y3Qgc2tfYnVmZiAqc2tiLCBzdHJ1Y3QgcnhfaGVhZGVyICpyeGhkcikKK3sKKwlzdHJ1Y3Qg bmV0X2RldmljZSAqbmRldiA9IGF4X2xvY2FsLT5uZGV2OworCXN0cnVjdCBheDg4Nzk2Y19wY3B1 X3N0YXRzICpzdGF0czsKKwlpbnQgc3RhdHVzOworCisJc3RhdHMgPSB0aGlzX2NwdV9wdHIoYXhf bG9jYWwtPnN0YXRzKTsKKworCWRvIHsKKwkJaWYgKCEobmRldi0+ZmVhdHVyZXMgJiBORVRJRl9G X1JYQ1NVTSkpCisJCQlicmVhazsKKworCQkvKiBjaGVja3N1bSBlcnJvciBiaXQgaXMgc2V0ICov CisJCWlmICgocnhoZHItPmZsYWdzICYgUlhfSERSM19MM19FUlIpIHx8CisJCSAgICAocnhoZHIt PmZsYWdzICYgUlhfSERSM19MNF9FUlIpKQorCQkJYnJlYWs7CisKKwkJLyogT3RoZXIgdHlwZXMg bWF5IGJlIGluZGljYXRlZCBieSBtb3JlIHRoYW4gb25lIGJpdC4gKi8KKwkJaWYgKChyeGhkci0+ ZmxhZ3MgJiBSWF9IRFIzX0w0X1RZUEVfVENQKSB8fAorCQkgICAgKHJ4aGRyLT5mbGFncyAmIFJY X0hEUjNfTDRfVFlQRV9VRFApKQorCQkJc2tiLT5pcF9zdW1tZWQgPSBDSEVDS1NVTV9VTk5FQ0VT U0FSWTsKKwl9IHdoaWxlICgwKTsKKworCXU2NF9zdGF0c191cGRhdGVfYmVnaW4oJnN0YXRzLT5z eW5jcCk7CisJdTY0X3N0YXRzX2luYygmc3RhdHMtPnJ4X3BhY2tldHMpOworCXU2NF9zdGF0c19h ZGQoJnN0YXRzLT5yeF9ieXRlcywgc2tiLT5sZW4pOworCXU2NF9zdGF0c191cGRhdGVfZW5kKCZz dGF0cy0+c3luY3ApOworCisJc2tiLT5kZXYgPSBuZGV2OworCXNrYi0+cHJvdG9jb2wgPSBldGhf dHlwZV90cmFucyhza2IsIGF4X2xvY2FsLT5uZGV2KTsKKworCW5ldGlmX2luZm8oYXhfbG9jYWws IHJ4X3N0YXR1cywgbmRldiwgIjwgcngsIGxlbiAlenUsIHR5cGUgMHgleFxuIiwKKwkJICAgc2ti LT5sZW4gKyBzaXplb2Yoc3RydWN0IGV0aGhkciksIHNrYi0+cHJvdG9jb2wpOworCisJc3RhdHVz ID0gbmV0aWZfcnhfbmkoc2tiKTsKKwlpZiAoc3RhdHVzICE9IE5FVF9SWF9TVUNDRVNTICYmIG5l dF9yYXRlbGltaXQoKSkKKwkJbmV0aWZfaW5mbyhheF9sb2NhbCwgcnhfZXJyLCBuZGV2LAorCQkJ ICAgIm5ldGlmX3J4IHN0YXR1cyAlZFxuIiwgc3RhdHVzKTsKK30KKworc3RhdGljIHZvaWQKK2F4 ODg3OTZjX3J4X2ZpeHVwKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsLCBzdHJ1Y3Qg c2tfYnVmZiAqcnhfc2tiKQoreworCXN0cnVjdCByeF9oZWFkZXIgKnJ4aGRyID0gKHN0cnVjdCBy eF9oZWFkZXIgKilyeF9za2ItPmRhdGE7CisJc3RydWN0IG5ldF9kZXZpY2UgKm5kZXYgPSBheF9s b2NhbC0+bmRldjsKKwl1MTYgbGVuOworCisJYmUxNl90b19jcHVzKCZyeGhkci0+ZmxhZ3NfbGVu KTsKKwliZTE2X3RvX2NwdXMoJnJ4aGRyLT5zZXFfbGVuYmFyKTsKKwliZTE2X3RvX2NwdXMoJnJ4 aGRyLT5mbGFncyk7CisKKwlpZiAoKHJ4aGRyLT5mbGFnc19sZW4gJiBSWF9IRFIxX1BLVF9MRU4p ICE9CisJCQkgKH5yeGhkci0+c2VxX2xlbmJhciAmIDB4N0ZGKSkgeworCQluZXRpZl9lcnIoYXhf bG9jYWwsIHJ4X2VyciwgbmRldiwgIkhlYWRlciBlcnJvclxuIik7CisKKwkJdGhpc19jcHVfaW5j KGF4X2xvY2FsLT5zdGF0cy0+cnhfZnJhbWVfZXJyb3JzKTsKKwkJa2ZyZWVfc2tiKHJ4X3NrYik7 CisJCXJldHVybjsKKwl9CisKKwlpZiAoKHJ4aGRyLT5mbGFnc19sZW4gJiBSWF9IRFIxX01JSV9F UlIpIHx8CisJICAgIChyeGhkci0+ZmxhZ3NfbGVuICYgUlhfSERSMV9DUkNfRVJSKSkgeworCQlu ZXRpZl9lcnIoYXhfbG9jYWwsIHJ4X2VyciwgbmRldiwgIkNSQyBvciBNSUkgZXJyb3JcbiIpOwor CisJCXRoaXNfY3B1X2luYyhheF9sb2NhbC0+c3RhdHMtPnJ4X2NyY19lcnJvcnMpOworCQlrZnJl ZV9za2Iocnhfc2tiKTsKKwkJcmV0dXJuOworCX0KKworCWxlbiA9IHJ4aGRyLT5mbGFnc19sZW4g JiBSWF9IRFIxX1BLVF9MRU47CisJaWYgKG5ldGlmX21zZ19wa3RkYXRhKGF4X2xvY2FsKSkgewor CQljaGFyIHBmeFtJRk5BTVNJWiArIDddOworCisJCXNucHJpbnRmKHBmeCwgc2l6ZW9mKHBmeCks ICIlczogICAgICIsIG5kZXYtPm5hbWUpOworCQluZXRkZXZfaW5mbyhuZGV2LCAiUlggZGF0YSwg dG90YWwgbGVuICVkLCBwYWNrZXQgbGVuICVkXG4iLAorCQkJICAgIHJ4X3NrYi0+bGVuLCBsZW4p OworCisJCW5ldGRldl9pbmZvKG5kZXYsICIgIER1bXAgUlggcGFja2V0IGhlYWRlcjoiKTsKKwkJ cHJpbnRfaGV4X2R1bXAoS0VSTl9JTkZPLCBwZngsIERVTVBfUFJFRklYX09GRlNFVCwgMTYsIDEs CisJCQkgICAgICAgcnhfc2tiLT5kYXRhLCBzaXplb2YoKnJ4aGRyKSwgMCk7CisKKwkJbmV0ZGV2 X2luZm8obmRldiwgIiAgRHVtcCBSWCBwYWNrZXQ6Iik7CisJCXByaW50X2hleF9kdW1wKEtFUk5f SU5GTywgcGZ4LCBEVU1QX1BSRUZJWF9PRkZTRVQsIDE2LCAxLAorCQkJICAgICAgIHJ4X3NrYi0+ ZGF0YSArIHNpemVvZigqcnhoZHIpLCBsZW4sIDApOworCX0KKworCXNrYl9wdWxsKHJ4X3NrYiwg c2l6ZW9mKCpyeGhkcikpOworCXBza2JfdHJpbShyeF9za2IsIGxlbik7CisKKwlheDg4Nzk2Y19z a2JfcmV0dXJuKGF4X2xvY2FsLCByeF9za2IsIHJ4aGRyKTsKK30KKworc3RhdGljIGludCBheDg4 Nzk2Y19yZWNlaXZlKHN0cnVjdCBuZXRfZGV2aWNlICpuZGV2KQoreworCXN0cnVjdCBheDg4Nzk2 Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9fYXg4ODc5NmNfZGV2aWNlKG5kZXYpOworCXN0cnVjdCBz a2JfZGF0YSAqZW50cnk7CisJdTE2IHdfY291bnQsIHBrdF9sZW47CisJc3RydWN0IHNrX2J1ZmYg KnNrYjsKKwl1OCBwa3RfY250OworCisJbG9ja2RlcF9hc3NlcnRfaGVsZCgmYXhfbG9jYWwtPnNw aV9sb2NrKTsKKworCS8qIGNoZWNrIHJ4IHBhY2tldCBhbmQgdG90YWwgd29yZCBjb3VudCAqLwor CUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQ MF9SVFdDUikKKwkJICB8IFJUV0NSX1JYX0xBVENILCBQMF9SVFdDUik7CisKKwlwa3RfY250ID0g QVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDBfUlhCQ1IyKSAmIFJYQkNSMl9QS1RfTUFTSzsK KwlpZiAoIXBrdF9jbnQpCisJCXJldHVybiAwOworCisJcGt0X2xlbiA9IEFYX1JFQUQoJmF4X2xv Y2FsLT5heF9zcGksIFAwX1JDUEhSKSAmIDB4N0ZGOworCisJd19jb3VudCA9IHJvdW5kX3VwKHBr dF9sZW4gKyA2LCA0KSA+PiAxOworCisJc2tiID0gbmV0ZGV2X2FsbG9jX3NrYihuZGV2LCB3X2Nv dW50ICogMik7CisJaWYgKCFza2IpIHsKKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIFJY QkNSMV9SWEJfRElTQ0FSRCwgUDBfUlhCQ1IxKTsKKwkJdGhpc19jcHVfaW5jKGF4X2xvY2FsLT5z dGF0cy0+cnhfZHJvcHBlZCk7CisJCXJldHVybiAwOworCX0KKwllbnRyeSA9IChzdHJ1Y3Qgc2ti X2RhdGEgKilza2ItPmNiOworCisJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIFJYQkNSMV9S WEJfU1RBUlQgfCB3X2NvdW50LCBQMF9SWEJDUjEpOworCisJYXhzcGlfcmVhZF9yeHEoJmF4X2xv Y2FsLT5heF9zcGksCisJCSAgICAgICBza2JfcHV0KHNrYiwgd19jb3VudCAqIDIpLCBza2ItPmxl bik7CisKKwkvKiBDaGVjayBpZiByeCBicmlkZ2UgaXMgaWRsZSAqLworCWlmICgoQVhfUkVBRCgm YXhfbG9jYWwtPmF4X3NwaSwgUDBfUlhCQ1IyKSAmIFJYQkNSMl9SWEJfSURMRSkgPT0gMCkgewor CQlpZiAobmV0X3JhdGVsaW1pdCgpKQorCQkJbmV0aWZfZXJyKGF4X2xvY2FsLCByeF9lcnIsIG5k ZXYsCisJCQkJICAiUnggQnJpZGdlIGlzIG5vdCBpZGxlXG4iKTsKKwkJQVhfV1JJVEUoJmF4X2xv Y2FsLT5heF9zcGksIFJYQkNSMl9SWEJfUkVJTklULCBQMF9SWEJDUjIpOworCisJCWVudHJ5LT5z dGF0ZSA9IHJ4X2VycjsKKwl9IGVsc2UgeworCQllbnRyeS0+c3RhdGUgPSByeF9kb25lOworCX0K KworCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBJU1JfUlhQS1QsIFAwX0lTUik7CisKKwlh eDg4Nzk2Y19yeF9maXh1cChheF9sb2NhbCwgc2tiKTsKKworCXJldHVybiAxOworfQorCitzdGF0 aWMgaW50IGF4ODg3OTZjX3Byb2Nlc3NfaXNyKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xv Y2FsKQoreworCXN0cnVjdCBuZXRfZGV2aWNlICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7CisJaW50 IHRvZG8gPSAwOworCXUxNiBpc3I7CisKKwlsb2NrZGVwX2Fzc2VydF9oZWxkKCZheF9sb2NhbC0+ c3BpX2xvY2spOworCisJaXNyID0gQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDBfSVNSKTsK KwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgaXNyLCBQMF9JU1IpOworCisJbmV0aWZfZGJn KGF4X2xvY2FsLCBpbnRyLCBuZGV2LCAiICBJU1IgMHglMDR4XG4iLCBpc3IpOworCisJaWYgKGlz ciAmIElTUl9UWEVSUikgeworCQluZXRpZl9kYmcoYXhfbG9jYWwsIGludHIsIG5kZXYsICIgIFRY RVJSIGludGVycnVwdFxuIik7CisJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCBUWE5SX1RY Ql9SRUlOSVQsIFAwX1RTTlIpOworCQlheF9sb2NhbC0+c2VxX251bSA9IDB4MWY7CisJfQorCisJ aWYgKGlzciAmIElTUl9UWFBBR0VTKSB7CisJCW5ldGlmX2RiZyhheF9sb2NhbCwgaW50ciwgbmRl diwgIiAgVFhQQUdFUyBpbnRlcnJ1cHRcbiIpOworCQlzZXRfYml0KEVWRU5UX1RYLCAmYXhfbG9j YWwtPmZsYWdzKTsKKwl9CisKKwlpZiAoaXNyICYgSVNSX0xJTkspIHsKKwkJbmV0aWZfZGJnKGF4 X2xvY2FsLCBpbnRyLCBuZGV2LCAiICBMaW5rIGNoYW5nZSBpbnRlcnJ1cHRcbiIpOworCQlwaHlf bWFjX2ludGVycnVwdChheF9sb2NhbC0+bmRldi0+cGh5ZGV2KTsKKwl9CisKKwlpZiAoaXNyICYg SVNSX1JYUEtUKSB7CisJCW5ldGlmX2RiZyhheF9sb2NhbCwgaW50ciwgbmRldiwgIiAgUlggaW50 ZXJydXB0XG4iKTsKKwkJdG9kbyA9IGF4ODg3OTZjX3JlY2VpdmUoYXhfbG9jYWwtPm5kZXYpOwor CX0KKworCXJldHVybiB0b2RvOworfQorCitzdGF0aWMgaXJxcmV0dXJuX3QgYXg4ODc5NmNfaW50 ZXJydXB0KGludCBpcnEsIHZvaWQgKmRldl9pbnN0YW5jZSkKK3sKKwlzdHJ1Y3QgYXg4ODc5NmNf ZGV2aWNlICpheF9sb2NhbDsKKwlzdHJ1Y3QgbmV0X2RldmljZSAqbmRldjsKKworCW5kZXYgPSBk ZXZfaW5zdGFuY2U7CisJaWYgKCFuZGV2KSB7CisJCXByX2VycigiaXJxICVkIGZvciB1bmtub3du IGRldmljZS5cbiIsIGlycSk7CisJCXJldHVybiBJUlFfUkVUVkFMKDApOworCX0KKwlheF9sb2Nh bCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2KTsKKworCWRpc2FibGVfaXJxX25vc3luYyhpcnEp OworCisJbmV0aWZfZGJnKGF4X2xvY2FsLCBpbnRyLCBuZGV2LCAiSW50ZXJydXB0IG9jY3VycmVk XG4iKTsKKworCXNldF9iaXQoRVZFTlRfSU5UUiwgJmF4X2xvY2FsLT5mbGFncyk7CisJc2NoZWR1 bGVfd29yaygmYXhfbG9jYWwtPmF4X3dvcmspOworCisJcmV0dXJuIElSUV9IQU5ETEVEOworfQor CitzdGF0aWMgdm9pZCBheDg4Nzk2Y193b3JrKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKK3sK KwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9CisJCQljb250YWluZXJfb2Yod29y aywgc3RydWN0IGF4ODg3OTZjX2RldmljZSwgYXhfd29yayk7CisKKwltdXRleF9sb2NrKCZheF9s b2NhbC0+c3BpX2xvY2spOworCisJaWYgKHRlc3RfYml0KEVWRU5UX1NFVF9NVUxUSSwgJmF4X2xv Y2FsLT5mbGFncykpIHsKKwkJYXg4ODc5NmNfc2V0X2h3X211bHRpY2FzdChheF9sb2NhbC0+bmRl dik7CisJCWNsZWFyX2JpdChFVkVOVF9TRVRfTVVMVEksICZheF9sb2NhbC0+ZmxhZ3MpOworCX0K KworCWlmICh0ZXN0X2JpdChFVkVOVF9JTlRSLCAmYXhfbG9jYWwtPmZsYWdzKSkgeworCQlBWF9X UklURSgmYXhfbG9jYWwtPmF4X3NwaSwgSU1SX01BU0tBTEwsIFAwX0lNUik7CisKKwkJd2hpbGUg KGF4ODg3OTZjX3Byb2Nlc3NfaXNyKGF4X2xvY2FsKSkKKwkJCS8qIG5vdGhpbmcgKi87CisKKwkJ Y2xlYXJfYml0KEVWRU5UX0lOVFIsICZheF9sb2NhbC0+ZmxhZ3MpOworCisJCUFYX1dSSVRFKCZh eF9sb2NhbC0+YXhfc3BpLCBJTVJfREVGQVVMVCwgUDBfSU1SKTsKKworCQllbmFibGVfaXJxKGF4 X2xvY2FsLT5uZGV2LT5pcnEpOworCX0KKworCWlmICh0ZXN0X2JpdChFVkVOVF9UWCwgJmF4X2xv Y2FsLT5mbGFncykpIHsKKwkJd2hpbGUgKHNrYl9xdWV1ZV9sZW4oJmF4X2xvY2FsLT50eF93YWl0 X3EpKSB7CisJCQlpZiAoIWF4ODg3OTZjX2hhcmRfeG1pdChheF9sb2NhbCkpCisJCQkJYnJlYWs7 CisJCX0KKworCQljbGVhcl9iaXQoRVZFTlRfVFgsICZheF9sb2NhbC0+ZmxhZ3MpOworCisJCWlm IChuZXRpZl9xdWV1ZV9zdG9wcGVkKGF4X2xvY2FsLT5uZGV2KSAmJgorCQkgICAgKHNrYl9xdWV1 ZV9sZW4oJmF4X2xvY2FsLT50eF93YWl0X3EpIDwgVFhfUVVFVUVfTE9XX1dBVEVSKSkKKwkJCW5l dGlmX3dha2VfcXVldWUoYXhfbG9jYWwtPm5kZXYpOworCX0KKworCW11dGV4X3VubG9jaygmYXhf bG9jYWwtPnNwaV9sb2NrKTsKK30KKworc3RhdGljIHZvaWQgYXg4ODc5NmNfZ2V0X3N0YXRzNjQo c3RydWN0IG5ldF9kZXZpY2UgKm5kZXYsCisJCQkJIHN0cnVjdCBydG5sX2xpbmtfc3RhdHM2NCAq c3RhdHMpCit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0b19heDg4Nzk2 Y19kZXZpY2UobmRldik7CisJdTMyIHJ4X2ZyYW1lX2Vycm9ycyA9IDAsIHJ4X2NyY19lcnJvcnMg PSAwOworCXUzMiByeF9kcm9wcGVkID0gMCwgdHhfZHJvcHBlZCA9IDA7CisJdW5zaWduZWQgaW50 IHN0YXJ0OworCWludCBjcHU7CisKKwlmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CisJCXN0 cnVjdCBheDg4Nzk2Y19wY3B1X3N0YXRzICpzOworCQl1NjQgcnhfcGFja2V0cywgcnhfYnl0ZXM7 CisJCXU2NCB0eF9wYWNrZXRzLCB0eF9ieXRlczsKKworCQlzID0gcGVyX2NwdV9wdHIoYXhfbG9j YWwtPnN0YXRzLCBjcHUpOworCisJCWRvIHsKKwkJCXN0YXJ0ID0gdTY0X3N0YXRzX2ZldGNoX2Jl Z2luX2lycSgmcy0+c3luY3ApOworCQkJcnhfcGFja2V0cyA9IHU2NF9zdGF0c19yZWFkKCZzLT5y eF9wYWNrZXRzKTsKKwkJCXJ4X2J5dGVzICAgPSB1NjRfc3RhdHNfcmVhZCgmcy0+cnhfYnl0ZXMp OworCQkJdHhfcGFja2V0cyA9IHU2NF9zdGF0c19yZWFkKCZzLT50eF9wYWNrZXRzKTsKKwkJCXR4 X2J5dGVzICAgPSB1NjRfc3RhdHNfcmVhZCgmcy0+dHhfYnl0ZXMpOworCQl9IHdoaWxlICh1NjRf c3RhdHNfZmV0Y2hfcmV0cnlfaXJxKCZzLT5zeW5jcCwgc3RhcnQpKTsKKworCQlzdGF0cy0+cnhf cGFja2V0cyArPSByeF9wYWNrZXRzOworCQlzdGF0cy0+cnhfYnl0ZXMgICArPSByeF9ieXRlczsK KwkJc3RhdHMtPnR4X3BhY2tldHMgKz0gdHhfcGFja2V0czsKKwkJc3RhdHMtPnR4X2J5dGVzICAg Kz0gdHhfYnl0ZXM7CisKKwkJcnhfZHJvcHBlZCAgICAgICs9IHN0YXRzLT5yeF9kcm9wcGVkOwor CQl0eF9kcm9wcGVkICAgICAgKz0gc3RhdHMtPnR4X2Ryb3BwZWQ7CisJCXJ4X2ZyYW1lX2Vycm9y cyArPSBzdGF0cy0+cnhfZnJhbWVfZXJyb3JzOworCQlyeF9jcmNfZXJyb3JzICAgKz0gc3RhdHMt PnJ4X2NyY19lcnJvcnM7CisJfQorCisJc3RhdHMtPnJ4X2Ryb3BwZWQgPSByeF9kcm9wcGVkOwor CXN0YXRzLT50eF9kcm9wcGVkID0gdHhfZHJvcHBlZDsKKwlzdGF0cy0+cnhfZnJhbWVfZXJyb3Jz ID0gcnhfZnJhbWVfZXJyb3JzOworCXN0YXRzLT5yeF9jcmNfZXJyb3JzID0gcnhfY3JjX2Vycm9y czsKK30KKworc3RhdGljIHZvaWQgYXg4ODc5NmNfc2V0X21hYyhzdHJ1Y3QgIGF4ODg3OTZjX2Rl dmljZSAqYXhfbG9jYWwpCit7CisJdTE2IG1hY2NyOworCisJbWFjY3IgPSAoYXhfbG9jYWwtPmxp bmspID8gTUFDQ1JfUlhFTiA6IDA7CisKKwlzd2l0Y2ggKGF4X2xvY2FsLT5zcGVlZCkgeworCWNh c2UgU1BFRURfMTAwOgorCQltYWNjciB8PSBNQUNDUl9TUEVFRF8xMDA7CisJY2FzZSBTUEVFRF8x MDoKKwljYXNlIFNQRUVEX1VOS05PV046CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCXJldHVybjsK Kwl9CisKKwlzd2l0Y2ggKGF4X2xvY2FsLT5kdXBsZXgpIHsKKwljYXNlIERVUExFWF9GVUxMOgor CQltYWNjciB8PSBNQUNDUl9TUEVFRF8xMDA7CisJY2FzZSBEVVBMRVhfSEFMRjoKKwljYXNlIERV UExFWF9VTktOT1dOOgorCQlicmVhazsKKwlkZWZhdWx0OgorCQlyZXR1cm47CisJfQorCisJaWYg KGF4X2xvY2FsLT5mbG93Y3RybCAmIEFYX0ZDX0FORUcgJiYKKwkgICAgYXhfbG9jYWwtPnBoeWRl di0+YXV0b25lZykgeworCQltYWNjciB8PSBheF9sb2NhbC0+cGF1c2UgPyBNQUNDUl9SWEZDX0VO QUJMRSA6IDA7CisJCW1hY2NyIHw9ICFheF9sb2NhbC0+cGF1c2UgIT0gIWF4X2xvY2FsLT5hc3lt X3BhdXNlID8KKwkJCU1BQ0NSX1RYRkNfRU5BQkxFIDogMDsKKwl9IGVsc2UgeworCQltYWNjciB8 PSAoYXhfbG9jYWwtPmZsb3djdHJsICYgQVhfRkNfUlgpID8gTUFDQ1JfUlhGQ19FTkFCTEUgOiAw OworCQltYWNjciB8PSAoYXhfbG9jYWwtPmZsb3djdHJsICYgQVhfRkNfVFgpID8gTUFDQ1JfVFhG Q19FTkFCTEUgOiAwOworCX0KKworCW11dGV4X2xvY2soJmF4X2xvY2FsLT5zcGlfbG9jayk7CisK KwltYWNjciB8PSBBWF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQMF9NQUNDUikgJgorCQl+KE1B Q0NSX0RVUExFWF9GVUxMIHwgTUFDQ1JfU1BFRURfMTAwIHwKKwkJICBNQUNDUl9UWEZDX0VOQUJM RSB8IE1BQ0NSX1JYRkNfRU5BQkxFKTsKKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgbWFj Y3IsIFAwX01BQ0NSKTsKKworCW11dGV4X3VubG9jaygmYXhfbG9jYWwtPnNwaV9sb2NrKTsKK30K Kworc3RhdGljIHZvaWQgYXg4ODc5NmNfaGFuZGxlX2xpbmtfY2hhbmdlKHN0cnVjdCBuZXRfZGV2 aWNlICpuZGV2KQoreworCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9fYXg4 ODc5NmNfZGV2aWNlKG5kZXYpOworCXN0cnVjdCBwaHlfZGV2aWNlICpwaHlkZXYgPSBuZGV2LT5w aHlkZXY7CisJYm9vbCB1cGRhdGUgPSBmYWxzZTsKKworCWlmIChwaHlkZXYtPmxpbmsgJiYgKGF4 X2xvY2FsLT5zcGVlZCAhPSBwaHlkZXYtPnNwZWVkIHx8CisJCQkgICAgIGF4X2xvY2FsLT5kdXBs ZXggIT0gcGh5ZGV2LT5kdXBsZXggfHwKKwkJCSAgICAgYXhfbG9jYWwtPnBhdXNlICE9IHBoeWRl di0+cGF1c2UgfHwKKwkJCSAgICAgYXhfbG9jYWwtPmFzeW1fcGF1c2UgIT0gcGh5ZGV2LT5hc3lt X3BhdXNlKSkgeworCQlheF9sb2NhbC0+c3BlZWQgPSBwaHlkZXYtPnNwZWVkOworCQlheF9sb2Nh bC0+ZHVwbGV4ID0gcGh5ZGV2LT5kdXBsZXg7CisJCWF4X2xvY2FsLT5wYXVzZSA9IHBoeWRldi0+ cGF1c2U7CisJCWF4X2xvY2FsLT5hc3ltX3BhdXNlID0gcGh5ZGV2LT5hc3ltX3BhdXNlOworCQl1 cGRhdGUgPSB0cnVlOworCX0KKworCWlmIChwaHlkZXYtPmxpbmsgIT0gYXhfbG9jYWwtPmxpbmsp IHsKKwkJaWYgKCFwaHlkZXYtPmxpbmspIHsKKwkJCWF4X2xvY2FsLT5zcGVlZCA9IFNQRUVEX1VO S05PV047CisJCQlheF9sb2NhbC0+ZHVwbGV4ID0gRFVQTEVYX1VOS05PV047CisJCX0KKworCQlh eF9sb2NhbC0+bGluayA9IHBoeWRldi0+bGluazsKKwkJdXBkYXRlID0gdHJ1ZTsKKwl9CisKKwlp ZiAodXBkYXRlKQorCQlheDg4Nzk2Y19zZXRfbWFjKGF4X2xvY2FsKTsKKworCWlmIChuZXRfcmF0 ZWxpbWl0KCkpCisJCXBoeV9wcmludF9zdGF0dXMobmRldi0+cGh5ZGV2KTsKK30KKworc3RhdGlj IHZvaWQgYXg4ODc5NmNfc2V0X2NzdW1zKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2Fs KQoreworCXN0cnVjdCBuZXRfZGV2aWNlICpuZGV2ID0gYXhfbG9jYWwtPm5kZXY7CisKKwlsb2Nr ZGVwX2Fzc2VydF9oZWxkKCZheF9sb2NhbC0+c3BpX2xvY2spOworCisJaWYgKG5kZXYtPmZlYXR1 cmVzICYgTkVUSUZfRl9SWENTVU0pIHsKKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIENP RVJDUjBfREVGQVVMVCwgUDRfQ09FUkNSMCk7CisJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3Bp LCBDT0VSQ1IxX0RFRkFVTFQsIFA0X0NPRVJDUjEpOworCX0gZWxzZSB7CisJCUFYX1dSSVRFKCZh eF9sb2NhbC0+YXhfc3BpLCAwLCBQNF9DT0VSQ1IwKTsKKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5h eF9zcGksIDAsIFA0X0NPRVJDUjEpOworCX0KKworCWlmIChuZGV2LT5mZWF0dXJlcyAmIE5FVElG X0ZfSFdfQ1NVTSkgeworCQlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgQ09FVENSMF9ERUZB VUxULCBQNF9DT0VUQ1IwKTsKKwkJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIENPRVRDUjFf VFhQUFBFLCBQNF9DT0VUQ1IxKTsKKwl9IGVsc2UgeworCQlBWF9XUklURSgmYXhfbG9jYWwtPmF4 X3NwaSwgMCwgUDRfQ09FVENSMCk7CisJCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCAwLCBQ NF9DT0VUQ1IxKTsKKwl9Cit9CisKK3N0YXRpYyBpbnQKK2F4ODg3OTZjX29wZW4oc3RydWN0IG5l dF9kZXZpY2UgKm5kZXYpCit7CisJc3RydWN0IGF4ODg3OTZjX2RldmljZSAqYXhfbG9jYWwgPSB0 b19heDg4Nzk2Y19kZXZpY2UobmRldik7CisJdW5zaWduZWQgbG9uZyBpcnFfZmxhZyA9IDA7CisJ aW50IGZjID0gQVhfRkNfTk9ORTsKKwlpbnQgcmV0OworCXUxNiB0OworCisJcmV0ID0gcmVxdWVz dF9pcnEobmRldi0+aXJxLCBheDg4Nzk2Y19pbnRlcnJ1cHQsCisJCQkgIGlycV9mbGFnLCBuZGV2 LT5uYW1lLCBuZGV2KTsKKwlpZiAocmV0KSB7CisJCW5ldGRldl9lcnIobmRldiwgInVuYWJsZSB0 byBnZXQgSVJRICVkIChlcnJubz0lZCkuXG4iLAorCQkJICAgbmRldi0+aXJxLCByZXQpOworCQly ZXR1cm4gcmV0OworCX0KKworCW11dGV4X2xvY2soJmF4X2xvY2FsLT5zcGlfbG9jayk7CisKKwly ZXQgPSBheDg4Nzk2Y19zb2Z0X3Jlc2V0KGF4X2xvY2FsKTsKKwlpZiAocmV0IDwgMCkgeworCQlm cmVlX2lycShuZGV2LT5pcnEsIG5kZXYpOworCQltdXRleF91bmxvY2soJmF4X2xvY2FsLT5zcGlf bG9jayk7CisJCXJldHVybiByZXQ7CisJfQorCWF4X2xvY2FsLT5zZXFfbnVtID0gMHgxZjsKKwor CWF4ODg3OTZjX3NldF9tYWNfYWRkcihuZGV2KTsKKwlheDg4Nzk2Y19zZXRfY3N1bXMoYXhfbG9j YWwpOworCisJLyogRGlzYWJsZSBzdHVmZmluZyBwYWNrZXQgKi8KKwl0ID0gQVhfUkVBRCgmYXhf bG9jYWwtPmF4X3NwaSwgUDFfUlhCU1BDUik7CisJdCAmPSB+UlhCU1BDUl9TVFVGX0VOQUJMRTsK KwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgdCwgUDFfUlhCU1BDUik7CisKKwkvKiBFbmFi bGUgUlggcGFja2V0IHByb2Nlc3MgKi8KKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgUlBQ RVJfUlhFTiwgUDFfUlBQRVIpOworCisJdCA9IEFYX1JFQUQoJmF4X2xvY2FsLT5heF9zcGksIFAw X0ZFUik7CisJdCB8PSBGRVJfUlhFTiB8IEZFUl9UWEVOIHwgRkVSX0JTV0FQIHwgRkVSX0lSUV9Q VUxMOworCUFYX1dSSVRFKCZheF9sb2NhbC0+YXhfc3BpLCB0LCBQMF9GRVIpOworCisJLyogU2V0 dXAgTEVEIG1vZGUgKi8KKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwKKwkJIChMQ1JfTEVE MF9FTiB8IExDUl9MRUQwX0RVUExFWCB8IExDUl9MRUQxX0VOIHwKKwkJIExDUl9MRUQxXzEwME1P REUpLCBQMl9MQ1IwKTsKKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwKKwkJIChBWF9SRUFE KCZheF9sb2NhbC0+YXhfc3BpLCBQMl9MQ1IxKSAmIExDUl9MRUQyX01BU0spIHwKKwkJIExDUl9M RUQyX0VOIHwgTENSX0xFRDJfTElOSywgUDJfTENSMSk7CisKKwkvKiBEaXNhYmxlIFBIWSBhdXRv LXBvbGxpbmcgKi8KKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgUENSX1BIWUlEKEFYODg3 OTZDX1BIWV9JRCksIFAyX1BDUik7CisKKwkvKiBFbmFibGUgTUFDIGludGVycnVwdHMgKi8KKwlB WF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgSU1SX0RFRkFVTFQsIFAwX0lNUik7CisKKwltdXRl eF91bmxvY2soJmF4X2xvY2FsLT5zcGlfbG9jayk7CisKKwkvKiBTZXR1cCBmbG93LWNvbnRyb2wg Y29uZmlndXJhdGlvbiAqLworCXBoeV9zdXBwb3J0X2FzeW1fcGF1c2UoYXhfbG9jYWwtPnBoeWRl dik7CisKKwlpZiAoYXhfbG9jYWwtPnBoeWRldi0+YWR2ZXJ0aXNpbmcgJiYKKwkgICAgKGxpbmtt b2RlX3Rlc3RfYml0KEVUSFRPT0xfTElOS19NT0RFX1BhdXNlX0JJVCwKKwkJCSAgICAgICBheF9s b2NhbC0+cGh5ZGV2LT5hZHZlcnRpc2luZykgfHwKKwkgICAgIGxpbmttb2RlX3Rlc3RfYml0KEVU SFRPT0xfTElOS19NT0RFX0FzeW1fUGF1c2VfQklULAorCQkJICAgICAgIGF4X2xvY2FsLT5waHlk ZXYtPmFkdmVydGlzaW5nKSkpCisJCWZjIHw9IEFYX0ZDX0FORUc7CisKKwlmYyB8PSBsaW5rbW9k ZV90ZXN0X2JpdChFVEhUT09MX0xJTktfTU9ERV9QYXVzZV9CSVQsCisJCQkJYXhfbG9jYWwtPnBo eWRldi0+YWR2ZXJ0aXNpbmcpID8gQVhfRkNfUlggOiAwOworCWZjIHw9IChsaW5rbW9kZV90ZXN0 X2JpdChFVEhUT09MX0xJTktfTU9ERV9QYXVzZV9CSVQsCisJCQkJIGF4X2xvY2FsLT5waHlkZXYt PmFkdmVydGlzaW5nKSAhPQorCSAgICAgICBsaW5rbW9kZV90ZXN0X2JpdChFVEhUT09MX0xJTktf TU9ERV9Bc3ltX1BhdXNlX0JJVCwKKwkJCQkgYXhfbG9jYWwtPnBoeWRldi0+YWR2ZXJ0aXNpbmcp KSA/IEFYX0ZDX1RYIDogMDsKKwlheF9sb2NhbC0+Zmxvd2N0cmwgPSBmYzsKKworCXBoeV9zdGFy dChheF9sb2NhbC0+bmRldi0+cGh5ZGV2KTsKKworCW5ldGlmX3N0YXJ0X3F1ZXVlKG5kZXYpOwor CisJc3BpX21lc3NhZ2VfaW5pdCgmYXhfbG9jYWwtPmF4X3NwaS5yeF9tc2cpOworCisJcmV0dXJu IDA7Cit9CisKK3N0YXRpYyBpbnQKK2F4ODg3OTZjX2Nsb3NlKHN0cnVjdCBuZXRfZGV2aWNlICpu ZGV2KQoreworCXN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9fYXg4ODc5NmNf ZGV2aWNlKG5kZXYpOworCisJbmV0aWZfc3RvcF9xdWV1ZShuZGV2KTsKKwlwaHlfc3RvcChuZGV2 LT5waHlkZXYpOworCisJbXV0ZXhfbG9jaygmYXhfbG9jYWwtPnNwaV9sb2NrKTsKKworCS8qIERp c2FibGUgTUFDIGludGVycnVwdHMgKi8KKwlBWF9XUklURSgmYXhfbG9jYWwtPmF4X3NwaSwgSU1S X01BU0tBTEwsIFAwX0lNUik7CisJX19za2JfcXVldWVfcHVyZ2UoJmF4X2xvY2FsLT50eF93YWl0 X3EpOworCWF4ODg3OTZjX3NvZnRfcmVzZXQoYXhfbG9jYWwpOworCisJbXV0ZXhfdW5sb2NrKCZh eF9sb2NhbC0+c3BpX2xvY2spOworCisJZnJlZV9pcnEobmRldi0+aXJxLCBuZGV2KTsKKworCXJl dHVybiAwOworfQorCitzdGF0aWMgaW50CitheDg4Nzk2Y19zZXRfZmVhdHVyZXMoc3RydWN0IG5l dF9kZXZpY2UgKm5kZXYsIG5ldGRldl9mZWF0dXJlc190IGZlYXR1cmVzKQoreworCXN0cnVjdCBh eDg4Nzk2Y19kZXZpY2UgKmF4X2xvY2FsID0gdG9fYXg4ODc5NmNfZGV2aWNlKG5kZXYpOworCW5l dGRldl9mZWF0dXJlc190IGNoYW5nZWQgPSBmZWF0dXJlcyBeIG5kZXYtPmZlYXR1cmVzOworCisJ aWYgKCEoY2hhbmdlZCAmIChORVRJRl9GX1JYQ1NVTSB8IE5FVElGX0ZfSFdfQ1NVTSkpKQorCQly ZXR1cm4gMDsKKworCW5kZXYtPmZlYXR1cmVzID0gZmVhdHVyZXM7CisKKwlpZiAoY2hhbmdlZCAm IChORVRJRl9GX1JYQ1NVTSB8IE5FVElGX0ZfSFdfQ1NVTSkpCisJCWF4ODg3OTZjX3NldF9jc3Vt cyhheF9sb2NhbCk7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBuZXRf ZGV2aWNlX29wcyBheDg4Nzk2Y19uZXRkZXZfb3BzID0geworCS5uZG9fb3BlbgkJPSBheDg4Nzk2 Y19vcGVuLAorCS5uZG9fc3RvcAkJPSBheDg4Nzk2Y19jbG9zZSwKKwkubmRvX3N0YXJ0X3htaXQJ CT0gYXg4ODc5NmNfc3RhcnRfeG1pdCwKKwkubmRvX2dldF9zdGF0czY0CT0gYXg4ODc5NmNfZ2V0 X3N0YXRzNjQsCisJLm5kb19kb19pb2N0bAkJPSBheDg4Nzk2Y19pb2N0bCwKKwkubmRvX3NldF9t YWNfYWRkcmVzcwk9IGV0aF9tYWNfYWRkciwKKwkubmRvX3NldF9mZWF0dXJlcwk9IGF4ODg3OTZj X3NldF9mZWF0dXJlcywKK307CisKK3N0YXRpYyBpbnQgYXg4ODc5NmNfaGFyZF9yZXNldChzdHJ1 Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCkKK3sKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAo c3RydWN0IGRldmljZSAqKSZheF9sb2NhbC0+c3BpLT5kZXY7CisJc3RydWN0IGdwaW9fZGVzYyAq cmVzZXRfZ3BpbzsKKworCS8qIHJlc2V0IGluZm8gKi8KKwlyZXNldF9ncGlvID0gZ3Bpb2RfZ2V0 KGRldiwgInJlc2V0IiwgMCk7CisJaWYgKElTX0VSUihyZXNldF9ncGlvKSkgeworCQlkZXZfZXJy KGRldiwgIkNvdWxkIG5vdCBnZXQgJ3Jlc2V0JyBHUElPOiAlbGQiLCBQVFJfRVJSKHJlc2V0X2dw aW8pKTsKKwkJcmV0dXJuIFBUUl9FUlIocmVzZXRfZ3Bpbyk7CisJfQorCisJLyogc2V0IHJlc2V0 ICovCisJZ3Bpb2RfZGlyZWN0aW9uX291dHB1dChyZXNldF9ncGlvLCAxKTsKKwltc2xlZXAoMTAw KTsKKwlncGlvZF9kaXJlY3Rpb25fb3V0cHV0KHJlc2V0X2dwaW8sIDApOworCWdwaW9kX3B1dChy ZXNldF9ncGlvKTsKKwltc2xlZXAoMjApOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQg YXg4ODc5NmNfcHJvYmUoc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkKK3sKKwljaGFyIHBoeV9pZFtN SUlfQlVTX0lEX1NJWkUgKyAzXTsKKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbDsK KwlzdHJ1Y3QgbmV0X2RldmljZSAqbmRldjsKKwl1MTYgdGVtcDsKKwlpbnQgcmV0OworCisJbmRl diA9IGRldm1fYWxsb2NfZXRoZXJkZXYoJnNwaS0+ZGV2LCBzaXplb2YoKmF4X2xvY2FsKSk7CisJ aWYgKCFuZGV2KQorCQlyZXR1cm4gLUVOT01FTTsKKworCVNFVF9ORVRERVZfREVWKG5kZXYsICZz cGktPmRldik7CisKKwlheF9sb2NhbCA9IHRvX2F4ODg3OTZjX2RldmljZShuZGV2KTsKKworCWRl dl9zZXRfZHJ2ZGF0YSgmc3BpLT5kZXYsIGF4X2xvY2FsKTsKKwlheF9sb2NhbC0+c3BpID0gc3Bp OworCWF4X2xvY2FsLT5heF9zcGkuc3BpID0gc3BpOworCisJYXhfbG9jYWwtPnN0YXRzID0KKwkJ ZGV2bV9uZXRkZXZfYWxsb2NfcGNwdV9zdGF0cygmc3BpLT5kZXYsCisJCQkJCSAgICAgc3RydWN0 IGF4ODg3OTZjX3BjcHVfc3RhdHMpOworCWlmICghYXhfbG9jYWwtPnN0YXRzKQorCQlyZXR1cm4g LUVOT01FTTsKKworCWF4X2xvY2FsLT5uZGV2ID0gbmRldjsKKwlheF9sb2NhbC0+cHJpdl9mbGFn cyB8PSBjb21wID8gQVhfQ0FQX0NPTVAgOiAwOworCWF4X2xvY2FsLT5tc2dfZW5hYmxlID0gbXNn X2VuYWJsZTsKKwltdXRleF9pbml0KCZheF9sb2NhbC0+c3BpX2xvY2spOworCisJYXhfbG9jYWwt Pm1kaW9idXMgPSBkZXZtX21kaW9idXNfYWxsb2MoJnNwaS0+ZGV2KTsKKwlpZiAoIWF4X2xvY2Fs LT5tZGlvYnVzKQorCQlyZXR1cm4gLUVOT01FTTsKKworCWF4X2xvY2FsLT5tZGlvYnVzLT5wcml2 ID0gYXhfbG9jYWw7CisJYXhfbG9jYWwtPm1kaW9idXMtPnJlYWQgPSBheDg4Nzk2Y19tZGlvX3Jl YWQ7CisJYXhfbG9jYWwtPm1kaW9idXMtPndyaXRlID0gYXg4ODc5NmNfbWRpb193cml0ZTsKKwlh eF9sb2NhbC0+bWRpb2J1cy0+bmFtZSA9ICJheDg4OTc2Yy1tZGlvYnVzIjsKKwlheF9sb2NhbC0+ bWRpb2J1cy0+cGh5X21hc2sgPSAodTMyKX5CSVQoQVg4ODc5NkNfUEhZX0lEKTsKKwlheF9sb2Nh bC0+bWRpb2J1cy0+cGFyZW50ID0gJnNwaS0+ZGV2OworCisJc25wcmludGYoYXhfbG9jYWwtPm1k aW9idXMtPmlkLCBNSUlfQlVTX0lEX1NJWkUsCisJCSAiYXg4ODc5NmMtJXMuJXUiLCBkZXZfbmFt ZSgmc3BpLT5kZXYpLCBzcGktPmNoaXBfc2VsZWN0KTsKKworCXJldCA9IGRldm1fbWRpb2J1c19y ZWdpc3Rlcigmc3BpLT5kZXYsIGF4X2xvY2FsLT5tZGlvYnVzKTsKKwlpZiAocmV0IDwgMCkgewor CQlkZXZfZXJyKCZzcGktPmRldiwgIkNvdWxkIG5vdCByZWdpc3RlciBNRElPIGJ1c1xuIik7CisJ CXJldHVybiByZXQ7CisJfQorCisJaWYgKG5ldGlmX21zZ19wcm9iZShheF9sb2NhbCkpIHsKKwkJ ZGV2X2luZm8oJnNwaS0+ZGV2LCAiQVg4ODc5NkMtU1BJIENvbmZpZ3VyYXRpb246XG4iKTsKKwkJ ZGV2X2luZm8oJnNwaS0+ZGV2LCAiICAgIENvbXByZXNzaW9uIDogJXNcbiIsCisJCQkgYXhfbG9j YWwtPnByaXZfZmxhZ3MgJiBBWF9DQVBfQ09NUCA/ICJPTiIgOiAiT0ZGIik7CisJfQorCisJbmRl di0+aXJxID0gc3BpLT5pcnE7CisJbmRldi0+bmV0ZGV2X29wcyA9ICZheDg4Nzk2Y19uZXRkZXZf b3BzOworCW5kZXYtPmV0aHRvb2xfb3BzID0gJmF4ODg3OTZjX2V0aHRvb2xfb3BzOworCW5kZXYt Pmh3X2ZlYXR1cmVzIHw9IE5FVElGX0ZfSFdfQ1NVTSB8IE5FVElGX0ZfUlhDU1VNOworCW5kZXYt PmZlYXR1cmVzIHw9IE5FVElGX0ZfSFdfQ1NVTSB8IE5FVElGX0ZfUlhDU1VNOworCW5kZXYtPm5l ZWRlZF9oZWFkcm9vbSA9IFRYX09WRVJIRUFEOworCW5kZXYtPm5lZWRlZF90YWlscm9vbSA9IFRY X0VPUF9TSVpFOworCisJbXV0ZXhfbG9jaygmYXhfbG9jYWwtPnNwaV9sb2NrKTsKKworCS8qIGF4 ODg3OTZjIGdwaW8gcmVzZXQgKi8KKwlheDg4Nzk2Y19oYXJkX3Jlc2V0KGF4X2xvY2FsKTsKKwor CS8qIFJlc2V0IEFYODg3OTZDICovCisJcmV0ID0gYXg4ODc5NmNfc29mdF9yZXNldChheF9sb2Nh bCk7CisJaWYgKHJldCA8IDApIHsKKwkJcmV0ID0gLUVOT0RFVjsKKwkJbXV0ZXhfdW5sb2NrKCZh eF9sb2NhbC0+c3BpX2xvY2spOworCQlnb3RvIGVycjsKKwl9CisJLyogQ2hlY2sgYm9hcmQgcmV2 aXNpb24gKi8KKwl0ZW1wID0gQVhfUkVBRCgmYXhfbG9jYWwtPmF4X3NwaSwgUDJfQ1JJUik7CisJ aWYgKCh0ZW1wICYgMHhGKSAhPSAweDApIHsKKwkJZGV2X2Vycigmc3BpLT5kZXYsICJzcGkgcmVh ZCBmYWlsZWQ6ICVkXG4iLCB0ZW1wKTsKKwkJcmV0ID0gLUVOT0RFVjsKKwkJbXV0ZXhfdW5sb2Nr KCZheF9sb2NhbC0+c3BpX2xvY2spOworCQlnb3RvIGVycjsKKwl9CisKKwkvKlJlbG9hZCBFRVBS T00qLworCWF4ODg3OTZjX3JlbG9hZF9lZXByb20oYXhfbG9jYWwpOworCisJYXg4ODc5NmNfbG9h ZF9tYWNfYWRkcihuZGV2KTsKKworCWlmIChuZXRpZl9tc2dfcHJvYmUoYXhfbG9jYWwpKQorCQlk ZXZfaW5mbygmc3BpLT5kZXYsCisJCQkgImlycSAlZCwgTUFDIGFkZHIgJTAyWDolMDJYOiUwMlg6 JTAyWDolMDJYOiUwMlhcbiIsCisJCQkgbmRldi0+aXJxLAorCQkJIG5kZXYtPmRldl9hZGRyWzBd LCBuZGV2LT5kZXZfYWRkclsxXSwKKwkJCSBuZGV2LT5kZXZfYWRkclsyXSwgbmRldi0+ZGV2X2Fk ZHJbM10sCisJCQkgbmRldi0+ZGV2X2FkZHJbNF0sIG5kZXYtPmRldl9hZGRyWzVdKTsKKworCS8q IERpc2FibGUgcG93ZXIgc2F2aW5nICovCisJQVhfV1JJVEUoJmF4X2xvY2FsLT5heF9zcGksIChB WF9SRUFEKCZheF9sb2NhbC0+YXhfc3BpLCBQMF9QU0NSKQorCQkJCSAgICAgJiBQU0NSX1BTX01B U0spIHwgUFNDUl9QU19EMCwgUDBfUFNDUik7CisKKwltdXRleF91bmxvY2soJmF4X2xvY2FsLT5z cGlfbG9jayk7CisKKwlJTklUX1dPUksoJmF4X2xvY2FsLT5heF93b3JrLCBheDg4Nzk2Y193b3Jr KTsKKworCXNrYl9xdWV1ZV9oZWFkX2luaXQoJmF4X2xvY2FsLT50eF93YWl0X3EpOworCisJc25w cmludGYocGh5X2lkLCBNSUlfQlVTX0lEX1NJWkUgKyAzLCBQSFlfSURfRk1ULAorCQkgYXhfbG9j YWwtPm1kaW9idXMtPmlkLCBBWDg4Nzk2Q19QSFlfSUQpOworCWF4X2xvY2FsLT5waHlkZXYgPSBw aHlfY29ubmVjdChheF9sb2NhbC0+bmRldiwgcGh5X2lkLAorCQkJCSAgICAgICBheDg4Nzk2Y19o YW5kbGVfbGlua19jaGFuZ2UsCisJCQkJICAgICAgIFBIWV9JTlRFUkZBQ0VfTU9ERV9NSUkpOwor CWlmIChJU19FUlIoYXhfbG9jYWwtPnBoeWRldikpIHsKKwkJcmV0ID0gUFRSX0VSUihheF9sb2Nh bC0+cGh5ZGV2KTsKKwkJZ290byBlcnI7CisJfQorCWF4X2xvY2FsLT5waHlkZXYtPmlycSA9IFBI WV9QT0xMOworCisJcmV0ID0gZGV2bV9yZWdpc3Rlcl9uZXRkZXYoJnNwaS0+ZGV2LCBuZGV2KTsK KwlpZiAocmV0KSB7CisJCWRldl9lcnIoJnNwaS0+ZGV2LCAiZmFpbGVkIHRvIHJlZ2lzdGVyIGEg bmV0d29yayBkZXZpY2VcbiIpOworCQlnb3RvIGVycl9waHlfZGlzOworCX0KKworCW5ldGlmX2lu Zm8oYXhfbG9jYWwsIHByb2JlLCBuZGV2LCAiJXMgJXMgcmVnaXN0ZXJlZFxuIiwKKwkJICAgZGV2 X2RyaXZlcl9zdHJpbmcoJnNwaS0+ZGV2KSwKKwkJICAgZGV2X25hbWUoJnNwaS0+ZGV2KSk7CisJ cGh5X2F0dGFjaGVkX2luZm8oYXhfbG9jYWwtPnBoeWRldik7CisKKwlyZXR1cm4gMDsKKworZXJy X3BoeV9kaXM6CisJcGh5X2Rpc2Nvbm5lY3QoYXhfbG9jYWwtPnBoeWRldik7CitlcnI6CisJcmV0 dXJuIHJldDsKK30KKworc3RhdGljIGludCBheDg4Nzk2Y19yZW1vdmUoc3RydWN0IHNwaV9kZXZp Y2UgKnNwaSkKK3sKKwlzdHJ1Y3QgYXg4ODc5NmNfZGV2aWNlICpheF9sb2NhbCA9IGRldl9nZXRf ZHJ2ZGF0YSgmc3BpLT5kZXYpOworCXN0cnVjdCBuZXRfZGV2aWNlICpuZGV2ID0gYXhfbG9jYWwt Pm5kZXY7CisKKwlwaHlfZGlzY29ubmVjdChuZGV2LT5waHlkZXYpOworCisJY2FuY2VsX3dvcmtf c3luYygmYXhfbG9jYWwtPmF4X3dvcmspOworCisJbmV0aWZfaW5mbyhheF9sb2NhbCwgcHJvYmUs IG5kZXYsICJyZW1vdmluZyBuZXR3b3JrIGRldmljZSAlcyAlc1xuIiwKKwkJICAgZGV2X2RyaXZl cl9zdHJpbmcoJnNwaS0+ZGV2KSwKKwkJICAgZGV2X25hbWUoJnNwaS0+ZGV2KSk7CisKKwlyZXR1 cm4gMDsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgYXg4ODc5NmNfZHRf aWRzW10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJhc2l4LGF4ODg3OTZjIiB9LAorCXt9LAorfTsK K01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIGF4ODg3OTZjX2R0X2lkcyk7CisKK3N0YXRpYyBjb25z dCBzdHJ1Y3Qgc3BpX2RldmljZV9pZCBhc2l4X2lkW10gPSB7CisJeyAiYXg4ODc5NmMiLCAwIH0s CisJeyB9Cit9OworTU9EVUxFX0RFVklDRV9UQUJMRShzcGksIGFzaXhfaWQpOworCitzdGF0aWMg c3RydWN0IHNwaV9kcml2ZXIgYXg4ODc5NmNfc3BpX2RyaXZlciA9IHsKKwkuZHJpdmVyID0gewor CQkubmFtZSA9IERSVl9OQU1FLAorCQkub2ZfbWF0Y2hfdGFibGUgPSBvZl9tYXRjaF9wdHIoYXg4 ODc5NmNfZHRfaWRzKSwKKwl9LAorCS5wcm9iZSA9IGF4ODg3OTZjX3Byb2JlLAorCS5yZW1vdmUg PSBheDg4Nzk2Y19yZW1vdmUsCisJLmlkX3RhYmxlID0gYXNpeF9pZCwKK307CisKK3N0YXRpYyBf X2luaXQgaW50IGF4ODg3OTZjX3NwaV9pbml0KHZvaWQpCit7CisJaW50IHJldDsKKworCWJpdG1h cF96ZXJvKGF4ODg3OTZjX25vX3JlZ3NfbWFzaywgQVg4ODc5NkNfUkVHRFVNUF9MRU4pOworCXJl dCA9IGJpdG1hcF9wYXJzZShub19yZWdzX2xpc3QsIDM1LAorCQkJICAgYXg4ODc5NmNfbm9fcmVn c19tYXNrLCBBWDg4Nzk2Q19SRUdEVU1QX0xFTik7CisJaWYgKHJldCkgeworCQliaXRtYXBfZmls bChheDg4Nzk2Y19ub19yZWdzX21hc2ssIEFYODg3OTZDX1JFR0RVTVBfTEVOKTsKKwkJcHJfZXJy KCJJbnZhbGlkIGJpdG1hcCBkZXNjcmlwdGlvbiwgbWFza2luZyBhbGwgcmVnaXN0ZXJzXG4iKTsK Kwl9CisKKwlyZXR1cm4gc3BpX3JlZ2lzdGVyX2RyaXZlcigmYXg4ODc5NmNfc3BpX2RyaXZlcik7 Cit9CisKK3N0YXRpYyBfX2V4aXQgdm9pZCBheDg4Nzk2Y19zcGlfZXhpdCh2b2lkKQoreworCXNw aV91bnJlZ2lzdGVyX2RyaXZlcigmYXg4ODc5NmNfc3BpX2RyaXZlcik7Cit9CisKK21vZHVsZV9p bml0KGF4ODg3OTZjX3NwaV9pbml0KTsKK21vZHVsZV9leGl0KGF4ODg3OTZjX3NwaV9leGl0KTsK KworTU9EVUxFX0FVVEhPUigiQVNJWCIpOworTU9EVUxFX0RFU0NSSVBUSU9OKCJBU0lYIEFYODg3 OTZDIFNQSSBFdGhlcm5ldCBkcml2ZXIiKTsKK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsKZGlmZiAt LWdpdCBhL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfbWFpbi5oIGIvZHJpdmVy cy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19tYWluLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQK aW5kZXggMDAwMDAwMDAwMDAwLi44MDI2M2MzY2VmNzUKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2 ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX21haW4uaApAQCAtMCwwICsxLDU2OCBAQAor LyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seSAqLworLyoKKyAqIENvcHly aWdodCAoYykgMjAxMCBBU0lYIEVsZWN0cm9uaWNzIENvcnBvcmF0aW9uCisgKiBDb3B5cmlnaHQg KGMpIDIwMjAgU2Ftc3VuZyBFbGVjdHJvbmljcworICoKKyAqIEFTSVggQVg4ODc5NkMgU1BJIEZh c3QgRXRoZXJuZXQgTGludXggZHJpdmVyCisgKi8KKworI2lmbmRlZiBfQVg4ODc5NkNfTUFJTl9I CisjZGVmaW5lIF9BWDg4Nzk2Q19NQUlOX0gKKworI2luY2x1ZGUgPGxpbnV4L25ldGRldmljZS5o PgorI2luY2x1ZGUgPGxpbnV4L21paS5oPgorCisjaW5jbHVkZSAiYXg4ODc5NmNfc3BpLmgiCisK Ky8qIFRoZXNlIGlkZW50aWZ5IHRoZSBkcml2ZXIgYmFzZSB2ZXJzaW9uIGFuZCBtYXkgbm90IGJl IHJlbW92ZWQuICovCisjZGVmaW5lIERSVl9OQU1FCSJheDg4Nzk2YyIKKyNkZWZpbmUgQURQX05B TUUJIkFTSVggQVg4ODc5NkMgU1BJIEV0aGVybmV0IEFkYXB0ZXIiCisKKyNkZWZpbmUgVFhfUVVF VUVfSElHSF9XQVRFUgkJNDUJLyogVHggcXVldWUgaGlnaCB3YXRlciBtYXJrICovCisjZGVmaW5l IFRYX1FVRVVFX0xPV19XQVRFUgkJMjAJLyogVHggcXVldWUgbG93IHdhdGVyIG1hcmsgKi8KKwor I2RlZmluZSBBWDg4Nzk2Q19SRUdEVU1QX0xFTgkJMjU2CisjZGVmaW5lIEFYODg3OTZDX1BIWV9S RUdEVU1QX0xFTgkxNAorI2RlZmluZSBBWDg4Nzk2Q19QSFlfSUQJCQkweDEwCisKKyNkZWZpbmUg VFhfT1ZFUkhFQUQJCQk4CisjZGVmaW5lIFRYX0VPUF9TSVpFCQkJNAorCisjZGVmaW5lIEFYX01D QVNUX0ZJTFRFUl9TSVpFCQk4CisjZGVmaW5lIEFYX01BWF9NQ0FTVAkJCTY0CisjZGVmaW5lIEFY X01BWF9DTEsgICAgICAgICAgICAgICAgICAgICAgODAwMDAwMDAKKyNkZWZpbmUgVFhfSERSX1NP UF9ESUNGCQkJMHg4MDAwCisjZGVmaW5lIFRYX0hEUl9TT1BfQ1BISQkJCTB4NDAwMAorI2RlZmlu ZSBUWF9IRFJfU09QX0lOVAkJCTB4MjAwMAorI2RlZmluZSBUWF9IRFJfU09QX01ERVEJCQkweDEw MDAKKyNkZWZpbmUgVFhfSERSX1NPUF9QS1RMRU4JCTB4MDdGRgorI2RlZmluZSBUWF9IRFJfU09Q X1NFUU5VTQkJMHhGODAwCisjZGVmaW5lIFRYX0hEUl9TT1BfUEtUTEVOQkFSCQkweDA3RkYKKwor I2RlZmluZSBUWF9IRFJfU0VHX0ZTCQkJMHg4MDAwCisjZGVmaW5lIFRYX0hEUl9TRUdfTFMJCQkw eDQwMDAKKyNkZWZpbmUgVFhfSERSX1NFR19TRUdOVU0JCTB4MzgwMAorI2RlZmluZSBUWF9IRFJf U0VHX1NFR0xFTgkJMHgwNzAwCisjZGVmaW5lIFRYX0hEUl9TRUdfRU9GU1QJCTB4QzAwMAorI2Rl ZmluZSBUWF9IRFJfU0VHX1NPRlNUCQkweDM4MDAKKyNkZWZpbmUgVFhfSERSX1NFR19TRUdMRU5C QVIJCTB4MDdGRgorCisjZGVmaW5lIFRYX0hEUl9FT1BfU0VRTlVNCQkweEY4MDAKKyNkZWZpbmUg VFhfSERSX0VPUF9QS1RMRU4JCTB4MDdGRgorI2RlZmluZSBUWF9IRFJfRU9QX1NFUU5VTUJBUgkJ MHhGODAwCisjZGVmaW5lIFRYX0hEUl9FT1BfUEtUTEVOQkFSCQkweDA3RkYKKworLyogUnggaGVh ZGVyIGZpZWxkcyBtYXNrICovCisjZGVmaW5lIFJYX0hEUjFfTUNCQwkJCTB4ODAwMAorI2RlZmlu ZSBSWF9IRFIxX1NUVUZGX1BLVAkJMHg0MDAwCisjZGVmaW5lIFJYX0hEUjFfTUlJX0VSUgkJCTB4 MjAwMAorI2RlZmluZSBSWF9IRFIxX0NSQ19FUlIJCQkweDEwMDAKKyNkZWZpbmUgUlhfSERSMV9Q S1RfTEVOCQkJMHgwN0ZGCisKKyNkZWZpbmUgUlhfSERSMl9TRVFfTlVNCQkJMHhGODAwCisjZGVm aW5lIFJYX0hEUjJfUEtUX0xFTl9CQVIJCTB4N0ZGRgorCisjZGVmaW5lIFJYX0hEUjNfUEUJCQkw eDgwMDAKKyNkZWZpbmUgUlhfSERSM19MM19UWVBFX0lQVjRWNgkJMHg2MDAwCisjZGVmaW5lIFJY X0hEUjNfTDNfVFlQRV9JUAkJMHg0MDAwCisjZGVmaW5lIFJYX0hEUjNfTDNfVFlQRV9JUFY2CQkw eDIwMDAKKyNkZWZpbmUgUlhfSERSM19MNF9UWVBFX0lDTVBWNgkJMHgxNDAwCisjZGVmaW5lIFJY X0hEUjNfTDRfVFlQRV9UQ1AJCTB4MTAwMAorI2RlZmluZSBSWF9IRFIzX0w0X1RZUEVfSUdNUAkJ MHgwYzAwCisjZGVmaW5lIFJYX0hEUjNfTDRfVFlQRV9JQ01QCQkweDA4MDAKKyNkZWZpbmUgUlhf SERSM19MNF9UWVBFX1VEUAkJMHgwNDAwCisjZGVmaW5lIFJYX0hEUjNfTDNfRVJSCQkJMHgwMjAw CisjZGVmaW5lIFJYX0hEUjNfTDRfRVJSCQkJMHgwMTAwCisjZGVmaW5lIFJYX0hEUjNfUFJJT1JJ VFkoeCkJCSgoeCkgPDwgNCkKKyNkZWZpbmUgUlhfSERSM19TVFJJUAkJCTB4MDAwOAorI2RlZmlu ZSBSWF9IRFIzX1ZMQU5fSUQJCQkweDAwMDcKKworc3RydWN0IGF4ODg3OTZjX3BjcHVfc3RhdHMg eworCXU2NF9zdGF0c190IHJ4X3BhY2tldHM7CisJdTY0X3N0YXRzX3QgcnhfYnl0ZXM7CisJdTY0 X3N0YXRzX3QgdHhfcGFja2V0czsKKwl1NjRfc3RhdHNfdCB0eF9ieXRlczsKKwlzdHJ1Y3QgdTY0 X3N0YXRzX3N5bmMgc3luY3A7CisJdTMyIHJ4X2Ryb3BwZWQ7CisJdTMyIHR4X2Ryb3BwZWQ7CisJ dTMyIHJ4X2ZyYW1lX2Vycm9yczsKKwl1MzIgcnhfY3JjX2Vycm9yczsKK307CisKK3N0cnVjdCBh eDg4Nzk2Y19kZXZpY2UgeworCXN0cnVjdCBzcGlfZGV2aWNlCSpzcGk7CisJc3RydWN0IG5ldF9k ZXZpY2UJKm5kZXY7CisJc3RydWN0IGF4ODg3OTZjX3BjcHVfc3RhdHMgX19wZXJjcHUgKnN0YXRz OworCisJc3RydWN0IHdvcmtfc3RydWN0CWF4X3dvcms7CisKKwlzdHJ1Y3QgbXV0ZXgJCXNwaV9s b2NrOyAvKiBkZXZpY2UgYWNjZXNzICovCisKKwlzdHJ1Y3Qgc2tfYnVmZl9oZWFkCXR4X3dhaXRf cTsKKworCXN0cnVjdCBheHNwaV9kYXRhCWF4X3NwaTsKKworCXN0cnVjdCBtaWlfYnVzCQkqbWRp b2J1czsKKwlzdHJ1Y3QgcGh5X2RldmljZQkqcGh5ZGV2OworCisJaW50CQkJbXNnX2VuYWJsZTsK KworCXUxNgkJCXNlcV9udW07CisKKwl1OAkJCW11bHRpX2ZpbHRlcltBWF9NQ0FTVF9GSUxURVJf U0laRV07CisKKwlpbnQJCQlsaW5rOworCWludAkJCXNwZWVkOworCWludAkJCWR1cGxleDsKKwlp bnQJCQlwYXVzZTsKKwlpbnQJCQlhc3ltX3BhdXNlOworCWludAkJCWZsb3djdHJsOworCQkjZGVm aW5lIEFYX0ZDX05PTkUJCTAKKwkJI2RlZmluZSBBWF9GQ19SWAkJQklUKDApCisJCSNkZWZpbmUg QVhfRkNfVFgJCUJJVCgxKQorCQkjZGVmaW5lIEFYX0ZDX0FORUcJCUJJVCgyKQorCisJdTMyCQkJ cHJpdl9mbGFnczsKKwkJI2RlZmluZSBBWF9DQVBfQ09NUAkJQklUKDApCisJCSNkZWZpbmUgQVhf UFJJVl9GTEFHU19NQVNLCShBWF9DQVBfQ09NUCkKKworCXVuc2lnbmVkIGxvbmcJCWZsYWdzOwor CQkjZGVmaW5lIEVWRU5UX0lOVFIJCUJJVCgwKQorCQkjZGVmaW5lIEVWRU5UX1RYCQlCSVQoMSkK KwkJI2RlZmluZSBFVkVOVF9TRVRfTVVMVEkJCUJJVCgyKQorCit9OworCisjZGVmaW5lIHRvX2F4 ODg3OTZjX2RldmljZShuZGV2KSAoKHN0cnVjdCBheDg4Nzk2Y19kZXZpY2UgKiluZXRkZXZfcHJp dihuZGV2KSkKKworZW51bSBza2Jfc3RhdGUgeworCWlsbGVnYWwgPSAwLAorCXR4X2RvbmUsCisJ cnhfZG9uZSwKKwlyeF9lcnIsCit9OworCitzdHJ1Y3Qgc2tiX2RhdGEgeworCWVudW0gc2tiX3N0 YXRlIHN0YXRlOworCXNpemVfdCBsZW47Cit9OworCisvKiBBODg3OTZDIHJlZ2lzdGVyIGRlZmlu aXRpb24gKi8KKwkvKiBEZWZpbml0aW9uIG9mIFBBR0UwICovCisjZGVmaW5lIFAwX1BTUgkJKDB4 MDApCisJI2RlZmluZSBQU1JfREVWX1JFQURZCQlCSVQoNykKKwkjZGVmaW5lIFBTUl9SRVNFVAkJ KDAgPDwgMTUpCisJI2RlZmluZSBQU1JfUkVTRVRfQ0xSCQlCSVQoMTUpCisjZGVmaW5lIFAwX0JP UgkJKDB4MDIpCisjZGVmaW5lIFAwX0ZFUgkJKDB4MDQpCisJI2RlZmluZSBGRVJfSVBBTE0JCUJJ VCgwKQorCSNkZWZpbmUgRkVSX0RDUkMJCUJJVCgxKQorCSNkZWZpbmUgRkVSX1JIM00JCUJJVCgy KQorCSNkZWZpbmUgRkVSX0hFQURFUlNXQVAJCUJJVCg3KQorCSNkZWZpbmUgRkVSX1dTV0FQCQlC SVQoOCkKKwkjZGVmaW5lIEZFUl9CU1dBUAkJQklUKDkpCisJI2RlZmluZSBGRVJfSU5USEkJCUJJ VCgxMCkKKwkjZGVmaW5lIEZFUl9JTlRMTwkJKDAgPDwgMTApCisJI2RlZmluZSBGRVJfSVJRX1BV TEwJCUJJVCgxMSkKKwkjZGVmaW5lIEZFUl9SWEVOCQlCSVQoMTQpCisJI2RlZmluZSBGRVJfVFhF TgkJQklUKDE1KQorI2RlZmluZSBQMF9JU1IJCSgweDA2KQorCSNkZWZpbmUgSVNSX1JYUEtUCQlC SVQoMCkKKwkjZGVmaW5lIElTUl9NRFEJCQlCSVQoNCkKKwkjZGVmaW5lIElTUl9UWFQJCQlCSVQo NSkKKwkjZGVmaW5lIElTUl9UWFBBR0VTCQlCSVQoNikKKwkjZGVmaW5lIElTUl9UWEVSUgkJQklU KDgpCisJI2RlZmluZSBJU1JfTElOSwkJQklUKDkpCisjZGVmaW5lIFAwX0lNUgkJKDB4MDgpCisJ I2RlZmluZSBJTVJfUlhQS1QJCUJJVCgwKQorCSNkZWZpbmUgSU1SX01EUQkJCUJJVCg0KQorCSNk ZWZpbmUgSU1SX1RYVAkJCUJJVCg1KQorCSNkZWZpbmUgSU1SX1RYUEFHRVMJCUJJVCg2KQorCSNk ZWZpbmUgSU1SX1RYRVJSCQlCSVQoOCkKKwkjZGVmaW5lIElNUl9MSU5LCQlCSVQoOSkKKwkjZGVm aW5lIElNUl9NQVNLQUxMCQkoMHhGRkZGKQorCSNkZWZpbmUgSU1SX0RFRkFVTFQJCShJTVJfVFhF UlIpCisjZGVmaW5lIFAwX1dGQ1IJCSgweDBBKQorCSNkZWZpbmUgV0ZDUl9QTUVJTkQJCUJJVCgw KSAvKiBQTUUgaW5kaWNhdGlvbiAqLworCSNkZWZpbmUgV0ZDUl9QTUVUWVBFCQlCSVQoMSkgLyog UE1FIEkvTyB0eXBlICovCisJI2RlZmluZSBXRkNSX1BNRVBPTAkJQklUKDIpIC8qIFBNRSBwb2xh cml0eSAqLworCSNkZWZpbmUgV0ZDUl9QTUVSU1QJCUJJVCgzKSAvKiBSZXNldCBQTUUgKi8KKwkj ZGVmaW5lIFdGQ1JfU0xFRVAJCUJJVCg0KSAvKiBFbmFibGUgc2xlZXAgbW9kZSAqLworCSNkZWZp bmUgV0ZDUl9XQUtFVVAJCUJJVCg1KSAvKiBFbmFibGUgd2FrZXVwIG1vZGUgKi8KKwkjZGVmaW5l IFdGQ1JfV0FJVEVWRU5UCQlCSVQoNikgLyogUmVzZXJ2ZWQgKi8KKwkjZGVmaW5lIFdGQ1JfQ0xS V0FLRQkJQklUKDcpIC8qIENsZWFyIHdha2V1cCAqLworCSNkZWZpbmUgV0ZDUl9MSU5LQ0gJCUJJ VCg4KSAvKiBFbmFibGUgbGluayBjaGFuZ2UgKi8KKwkjZGVmaW5lIFdGQ1JfTUFHSUNQCQlCSVQo OSkgLyogRW5hYmxlIG1hZ2ljIHBhY2tldCAqLworCSNkZWZpbmUgV0ZDUl9XQUtFRgkJQklUKDEw KSAvKiBFbmFibGUgd2FrZXVwIGZyYW1lICovCisJI2RlZmluZSBXRkNSX1BNRUVOCQlCSVQoMTEp IC8qIEVuYWJsZSBQTUUgcGluICovCisJI2RlZmluZSBXRkNSX0xJTktDSFMJCUJJVCgxMikgLyog TGluayBjaGFuZ2Ugc3RhdHVzICovCisJI2RlZmluZSBXRkNSX01BR0lDUFMJCUJJVCgxMykgLyog TWFnaWMgcGFja2V0IHN0YXR1cyAqLworCSNkZWZpbmUgV0ZDUl9XQUtFRlMJCUJJVCgxNCkgLyog V2FrZXVwIGZyYW1lIHN0YXR1cyAqLworCSNkZWZpbmUgV0ZDUl9QTUVTCQlCSVQoMTUpIC8qIFBN RSBwaW4gc3RhdHVzICovCisjZGVmaW5lIFAwX1BTQ1IJCSgweDBDKQorCSNkZWZpbmUgUFNDUl9Q U19NQVNLCQkoMHhGRkYwKQorCSNkZWZpbmUgUFNDUl9QU19EMAkJKDApCisJI2RlZmluZSBQU0NS X1BTX0QxCQlCSVQoMCkKKwkjZGVmaW5lIFBTQ1JfUFNfRDIJCUJJVCgxKQorCSNkZWZpbmUgUFND Ul9GUFMJCUJJVCgzKSAvKiBFbmFibGUgZmliZXIgbW9kZSBQUyAqLworCSNkZWZpbmUgUFNDUl9T V1BTCQlCSVQoNCkgLyogRW5hYmxlIHNvZnR3YXJlICovCisJCQkJCQkgLyogUFMgY29udHJvbCAq LworCSNkZWZpbmUgUFNDUl9XT0xQUwkJQklUKDUpIC8qIEVuYWJsZSBXT0wgUFMgKi8KKwkjZGVm aW5lIFBTQ1JfU1dXT0wJCUJJVCg2KSAvKiBFbmFibGUgc29mdHdhcmUgc2VsZWN0ICovCisJCQkJ CQkgLyogV09MIFBTICovCisJI2RlZmluZSBQU0NSX1BIWU9TQwkJQklUKDcpIC8qIEludGVybmFs IFBIWSBPU0MgY29udHJvbCAqLworCSNkZWZpbmUgUFNDUl9GT0ZFRgkJQklUKDgpIC8qIEZvcmNl IFBIWSBnZW5lcmF0ZSBGRUYgKi8KKwkjZGVmaW5lIFBTQ1JfRk9GCQlCSVQoOSkgLyogRm9yY2Ug UEhZIGluIGZpYmVyIG1vZGUgKi8KKwkjZGVmaW5lIFBTQ1JfUEhZUEQJCUJJVCgxMCkgLyogUEhZ IHBvd2VyIGRvd24uICovCisJCQkJCQkgIC8qIEFjdGl2ZSBoaWdoICovCisJI2RlZmluZSBQU0NS X1BIWVJTVAkJQklUKDExKSAvKiBQSFkgcmVzZXQgc2lnbmFsLiAqLworCQkJCQkJICAvKiBBY3Rp dmUgbG93ICovCisJI2RlZmluZSBQU0NSX1BIWUNTSUwJCUJJVCgxMikgLyogUEhZIGNhYmxlIGVu ZXJneSBkZXRlY3QgKi8KKwkjZGVmaW5lIFBTQ1JfUEhZQ09GRgkJQklUKDEzKSAvKiBQSFkgY2Fi bGUgb2ZmICovCisJI2RlZmluZSBQU0NSX1BIWUxJTksJCUJJVCgxNCkgLyogUEhZIGxpbmsgc3Rh dHVzICovCisJI2RlZmluZSBQU0NSX0VFUE9LCQlCSVQoMTUpIC8qIEVFUFJPTSBsb2FkIGNvbXBs ZXRlICovCisjZGVmaW5lIFAwX01BQ0NSCSgweDBFKQorCSNkZWZpbmUgTUFDQ1JfUlhFTgkJQklU KDApIC8qIEVuYWJsZSBSWCAqLworCSNkZWZpbmUgTUFDQ1JfRFVQTEVYX0ZVTEwJQklUKDEpIC8q IDE6IEZ1bGwsIDA6IEhhbGYgKi8KKwkjZGVmaW5lIE1BQ0NSX1NQRUVEXzEwMAkJQklUKDIpIC8q IDE6IDEwME1icHMsIDA6IDEwTWJwcyAqLworCSNkZWZpbmUgTUFDQ1JfUlhGQ19FTkFCTEUJQklU KDMpCisJI2RlZmluZSBNQUNDUl9SWEZDX01BU0sJCTB4RkZGNworCSNkZWZpbmUgTUFDQ1JfVFhG Q19FTkFCTEUJQklUKDQpCisJI2RlZmluZSBNQUNDUl9UWEZDX01BU0sJCTB4RkZFRgorCSNkZWZp bmUgTUFDQ1JfUFNJCQlCSVQoNikgLyogU29mdHdhcmUgQ2FibGUtT2ZmICovCisJCQkJCSAgICAg ICAvKiBQb3dlciBTYXZpbmcgSW50ZXJydXB0ICovCisJI2RlZmluZSBNQUNDUl9QRgkJQklUKDcp CisJI2RlZmluZSBNQUNDUl9QTU1fQklUUwkJOAorCSNkZWZpbmUgTUFDQ1JfUE1NX01BU0sJCSgw eDFGMDApCisJI2RlZmluZSBNQUNDUl9QTU1fUkVTRVQJCUJJVCg4KQorCSNkZWZpbmUgTUFDQ1Jf UE1NX1dBSVQJCSgyIDw8IDgpCisJI2RlZmluZSBNQUNDUl9QTU1fUkVBRFkJCSgzIDw8IDgpCisJ I2RlZmluZSBNQUNDUl9QTU1fRDEJCSg0IDw8IDgpCisJI2RlZmluZSBNQUNDUl9QTU1fRDIJCSg1 IDw8IDgpCisJI2RlZmluZSBNQUNDUl9QTU1fV0FLRQkJKDcgPDwgOCkKKwkjZGVmaW5lIE1BQ0NS X1BNTV9EMV9XQUtFCSg4IDw8IDgpCisJI2RlZmluZSBNQUNDUl9QTU1fRDJfV0FLRQkoOSA8PCA4 KQorCSNkZWZpbmUgTUFDQ1JfUE1NX1NMRUVQCQkoMTAgPDwgOCkKKwkjZGVmaW5lIE1BQ0NSX1BN TV9QSFlfUkVTRVQJKDExIDw8IDgpCisJI2RlZmluZSBNQUNDUl9QTU1fU09GVF9EMQkoMTYgPDwg OCkKKwkjZGVmaW5lIE1BQ0NSX1BNTV9TT0ZUX0QyCSgxNyA8PCA4KQorI2RlZmluZSBQMF9URkJG Q1IJKDB4MTApCisJI2RlZmluZSBURkJGQ1JfU0NIRV9GUkVFX1BBR0UJMHhFMDdGCisJI2RlZmlu ZSBURkJGQ1JfRlJFRV9QQUdFX0JJVFMJMHgwNworCSNkZWZpbmUgVEZCRkNSX0ZSRUVfUEFHRV9M QVRDSAlCSVQoNikKKwkjZGVmaW5lIFRGQkZDUl9TRVRfRlJFRV9QQUdFKHgpCSgoKHgpICYgMHgz RikgPDwgVEZCRkNSX0ZSRUVfUEFHRV9CSVRTKQorCSNkZWZpbmUgVEZCRkNSX1RYX1BBR0VfU0VU CUJJVCgxMykKKwkjZGVmaW5lIFRGQkZDUl9NQU5VX0VOVFgJQklUKDE1KQorCSNkZWZpbmUgVFhf RlJFRUJVRl9NQVNLCQkweDAwM0YKKwkjZGVmaW5lIFRYX0RQVFNUQVJUCQkweDQwMDAKKworI2Rl ZmluZSBQMF9UU05SCQkoMHgxMikKKwkjZGVmaW5lIFRYTlJfVFhCX0VSUgkJQklUKDUpCisJI2Rl ZmluZSBUWE5SX1RYQl9JRExFCQlCSVQoNikKKwkjZGVmaW5lIFRTTlJfUEtUX0NOVCh4KQkJKCgo eCkgJiAweDNGKSA8PCA4KQorCSNkZWZpbmUgVFhOUl9UWEJfUkVJTklUCQlCSVQoMTQpCisJI2Rl ZmluZSBUU05SX1RYQl9TVEFSVAkJQklUKDE1KQorI2RlZmluZSBQMF9SVERQUgkoMHgxNCkKKyNk ZWZpbmUgUDBfUlhCQ1IxCSgweDE2KQorCSNkZWZpbmUgUlhCQ1IxX1JYQl9ESVNDQVJECUJJVCgx NCkKKwkjZGVmaW5lIFJYQkNSMV9SWEJfU1RBUlQJQklUKDE1KQorI2RlZmluZSBQMF9SWEJDUjIJ KDB4MTgpCisJI2RlZmluZSBSWEJDUjJfUEtUX01BU0sJCSgweEZGKQorCSNkZWZpbmUgUlhCQ1Iy X1JYUENfTUFTSwkoMHg3RikKKwkjZGVmaW5lIFJYQkNSMl9SWEJfUkVBRFkJQklUKDEzKQorCSNk ZWZpbmUgUlhCQ1IyX1JYQl9JRExFCQlCSVQoMTQpCisJI2RlZmluZSBSWEJDUjJfUlhCX1JFSU5J VAlCSVQoMTUpCisjZGVmaW5lIFAwX1JUV0NSCSgweDFBKQorCSNkZWZpbmUgUlRXQ1JfUlhXQ19N QVNLCQkoMHgzRkZGKQorCSNkZWZpbmUgUlRXQ1JfUlhfTEFUQ0gJCUJJVCgxNSkKKyNkZWZpbmUg UDBfUkNQSFIJKDB4MUMpCisKKwkvKiBEZWZpbml0aW9uIG9mIFBBR0UxICovCisjZGVmaW5lIFAx X1JQUEVSCSgweDIyKQorCSNkZWZpbmUgUlBQRVJfUlhFTgkJQklUKDApCisjZGVmaW5lIFAxX01S Q1IJCSgweDI4KQorI2RlZmluZSBQMV9NRFIJCSgweDJBKQorI2RlZmluZSBQMV9STVBSCQkoMHgy QykKKyNkZWZpbmUgUDFfVE1QUgkJKDB4MkUpCisjZGVmaW5lIFAxX1JYQlNQQ1IJKDB4MzApCisJ I2RlZmluZSBSWEJTUENSX1NUVUZfV09SRF9DTlQoeCkJKCgoeCkgJiAweDcwMDApID4+IDEyKQor CSNkZWZpbmUgUlhCU1BDUl9TVFVGX0VOQUJMRQkJQklUKDE1KQorI2RlZmluZSBQMV9NQ1IJCSgw eDMyKQorCSNkZWZpbmUgTUNSX1NCUAkJCUJJVCg4KQorCSNkZWZpbmUgTUNSX1NNCQkJQklUKDkp CisJI2RlZmluZSBNQ1JfQ1JDRU5MQU4JCUJJVCgxMSkKKwkjZGVmaW5lIE1DUl9TVFAJCQlCSVQo MTIpCisJLyogRGVmaW5pdGlvbiBvZiBQQUdFMiAqLworI2RlZmluZSBQMl9DSVIJCSgweDQyKQor I2RlZmluZSBQMl9QQ1IJCSgweDQ0KQorCSNkZWZpbmUgUENSX1BPTExfRU4JCUJJVCgwKQorCSNk ZWZpbmUgUENSX1BPTExfRkxPV0NUUkwJQklUKDEpCisJI2RlZmluZSBQQ1JfUE9MTF9CTUNSCQlC SVQoMikKKwkjZGVmaW5lIFBDUl9QSFlJRCh4KQkJKCh4KSA8PCA4KQorI2RlZmluZSBQMl9QSFlT UgkoMHg0NikKKyNkZWZpbmUgUDJfTURJT0RSCSgweDQ4KQorI2RlZmluZSBQMl9NRElPQ1IJKDB4 NEEpCisJI2RlZmluZSBNRElPQ1JfUkFERFIoeCkJCSgoeCkgJiAweDFGKQorCSNkZWZpbmUgTURJ T0NSX0ZBRERSKHgpCQkoKCh4KSAmIDB4MUYpIDw8IDgpCisJI2RlZmluZSBNRElPQ1JfVkFMSUQJ CUJJVCgxMykKKwkjZGVmaW5lIE1ESU9DUl9SRUFECQlCSVQoMTQpCisJI2RlZmluZSBNRElPQ1Jf V1JJVEUJCUJJVCgxNSkKKyNkZWZpbmUgUDJfTENSMAkJKDB4NEMpCisJI2RlZmluZSBMQ1JfTEVE MF9FTgkJQklUKDApCisJI2RlZmluZSBMQ1JfTEVEMF8xMDBNT0RFCUJJVCgxKQorCSNkZWZpbmUg TENSX0xFRDBfRFVQTEVYCQlCSVQoMikKKwkjZGVmaW5lIExDUl9MRUQwX0xJTksJCUJJVCgzKQor CSNkZWZpbmUgTENSX0xFRDBfQUNUCQlCSVQoNCkKKwkjZGVmaW5lIExDUl9MRUQwX0NPTAkJQklU KDUpCisJI2RlZmluZSBMQ1JfTEVEMF8xME1PREUJCUJJVCg2KQorCSNkZWZpbmUgTENSX0xFRDBf RFVQQ09MCQlCSVQoNykKKwkjZGVmaW5lIExDUl9MRUQxX0VOCQlCSVQoOCkKKwkjZGVmaW5lIExD Ul9MRUQxXzEwME1PREUJQklUKDkpCisJI2RlZmluZSBMQ1JfTEVEMV9EVVBMRVgJCUJJVCgxMCkK KwkjZGVmaW5lIExDUl9MRUQxX0xJTksJCUJJVCgxMSkKKwkjZGVmaW5lIExDUl9MRUQxX0FDVAkJ QklUKDEyKQorCSNkZWZpbmUgTENSX0xFRDFfQ09MCQlCSVQoMTMpCisJI2RlZmluZSBMQ1JfTEVE MV8xME1PREUJCUJJVCgxNCkKKwkjZGVmaW5lIExDUl9MRUQxX0RVUENPTAkJQklUKDE1KQorI2Rl ZmluZSBQMl9MQ1IxCQkoMHg0RSkKKwkjZGVmaW5lIExDUl9MRUQyX01BU0sJCSgweEZGMDApCisJ I2RlZmluZSBMQ1JfTEVEMl9FTgkJQklUKDApCisJI2RlZmluZSBMQ1JfTEVEMl8xMDBNT0RFCUJJ VCgxKQorCSNkZWZpbmUgTENSX0xFRDJfRFVQTEVYCQlCSVQoMikKKwkjZGVmaW5lIExDUl9MRUQy X0xJTksJCUJJVCgzKQorCSNkZWZpbmUgTENSX0xFRDJfQUNUCQlCSVQoNCkKKwkjZGVmaW5lIExD Ul9MRUQyX0NPTAkJQklUKDUpCisJI2RlZmluZSBMQ1JfTEVEMl8xME1PREUJCUJJVCg2KQorCSNk ZWZpbmUgTENSX0xFRDJfRFVQQ09MCQlCSVQoNykKKyNkZWZpbmUgUDJfSVBHQ1IJKDB4NTApCisj ZGVmaW5lIFAyX0NSSVIJCSgweDUyKQorI2RlZmluZSBQMl9GTEhXQ1IJKDB4NTQpCisjZGVmaW5l IFAyX1JYQ1IJCSgweDU2KQorCSNkZWZpbmUgUlhDUl9QUk8JCUJJVCgwKQorCSNkZWZpbmUgUlhD Ul9BTUFMTAkJQklUKDEpCisJI2RlZmluZSBSWENSX1NFUAkJQklUKDIpCisJI2RlZmluZSBSWENS X0FCCQkJQklUKDMpCisJI2RlZmluZSBSWENSX0FNCQkJQklUKDQpCisJI2RlZmluZSBSWENSX0FQ CQkJQklUKDUpCisJI2RlZmluZSBSWENSX0FSUAkJQklUKDYpCisjZGVmaW5lIFAyX0pMQ1IJCSgw eDU4KQorI2RlZmluZSBQMl9NUExSCQkoMHg1QykKKworCS8qIERlZmluaXRpb24gb2YgUEFHRTMg Ki8KKyNkZWZpbmUgUDNfTUFDQVNSMAkoMHg2MikKKwkjZGVmaW5lIFAzX01BQ0FTUih4KQkJKFAz X01BQ0FTUjAgKyAyICogKHgpKQorCSNkZWZpbmUgTUFDQVNSX0xPV0JZVEVfTUFTSwkweDAwRkYK KwkjZGVmaW5lIE1BQ0FTUl9ISUdIX0JJVFMJMHgwOAorI2RlZmluZSBQM19NQUNBU1IxCSgweDY0 KQorI2RlZmluZSBQM19NQUNBU1IyCSgweDY2KQorI2RlZmluZSBQM19NRkFSMDEJKDB4NjgpCisj ZGVmaW5lIFAzX01GQVJfQkFTRQkoMHg2OCkKKwkjZGVmaW5lIFAzX01GQVIoeCkJCShQM19NRkFS X0JBU0UgKyAyICogKHgpKQorCisjZGVmaW5lIFAzX01GQVIyMwkoMHg2QSkKKyNkZWZpbmUgUDNf TUZBUjQ1CSgweDZDKQorI2RlZmluZSBQM19NRkFSNjcJKDB4NkUpCisjZGVmaW5lIFAzX1ZJRDBG UgkoMHg3MCkKKyNkZWZpbmUgUDNfVklEMUZSCSgweDcyKQorI2RlZmluZSBQM19FRUNTUgkoMHg3 NCkKKyNkZWZpbmUgUDNfRUVEUgkJKDB4NzYpCisjZGVmaW5lIFAzX0VFQ1IJCSgweDc4KQorCSNk ZWZpbmUgRUVDUl9BRERSX01BU0sJCSgweDAwRkYpCisJI2RlZmluZSBFRUNSX1JFQURfQUNUCQlC SVQoOCkKKwkjZGVmaW5lIEVFQ1JfV1JJVEVfQUNUCQlCSVQoOSkKKwkjZGVmaW5lIEVFQ1JfV1JJ VEVfRElTQUJMRQlCSVQoMTApCisJI2RlZmluZSBFRUNSX1dSSVRFX0VOQUJMRQlCSVQoMTEpCisJ I2RlZmluZSBFRUNSX0VFX1JFQURZCQlCSVQoMTMpCisJI2RlZmluZSBFRUNSX1JFTE9BRAkJQklU KDE0KQorCSNkZWZpbmUgRUVDUl9SRVNFVAkJQklUKDE1KQorI2RlZmluZSBQM19UUENSCQkoMHg3 QSkKKwkjZGVmaW5lIFRQQ1JfUEFUVF9NQVNLCQkoMHhGRikKKwkjZGVmaW5lIFRQQ1JfUkFORF9Q S1RfRU4JQklUKDE0KQorCSNkZWZpbmUgVFBDUl9GSVhFRF9QS1RfRU4JQklUKDE1KQorI2RlZmlu ZSBQM19UUExSCQkoMHg3QykKKwkvKiBEZWZpbml0aW9uIG9mIFBBR0U0ICovCisjZGVmaW5lIFA0 X1NQSUNSCSgweDhBKQorCSNkZWZpbmUgU1BJQ1JfUkNFTgkJQklUKDApCisJI2RlZmluZSBTUElD Ul9RQ0VOCQlCSVQoMSkKKwkjZGVmaW5lIFNQSUNSX1JCUkUJCUJJVCgzKQorCSNkZWZpbmUgU1BJ Q1JfUE1NCQlCSVQoNCkKKwkjZGVmaW5lIFNQSUNSX0xPT1BCQUNLCQlCSVQoOCkKKwkjZGVmaW5l IFNQSUNSX0NPUkVfUkVTX0NMUglCSVQoMTApCisJI2RlZmluZSBTUElDUl9TUElfUkVTX0NMUglC SVQoMTEpCisjZGVmaW5lIFA0X1NQSUlTTVIJKDB4OEMpCisKKyNkZWZpbmUgUDRfQ09FUkNSMAko MHg5MikKKwkjZGVmaW5lIENPRVJDUjBfUlhJUENFCQlCSVQoMCkKKwkjZGVmaW5lIENPRVJDUjBf UlhJUFZFCQlCSVQoMSkKKwkjZGVmaW5lIENPRVJDUjBfUlhWNlBFCQlCSVQoMikKKwkjZGVmaW5l IENPRVJDUjBfUlhUQ1BFCQlCSVQoMykKKwkjZGVmaW5lIENPRVJDUjBfUlhVRFBFCQlCSVQoNCkK KwkjZGVmaW5lIENPRVJDUjBfUlhJQ01QCQlCSVQoNSkKKwkjZGVmaW5lIENPRVJDUjBfUlhJR01Q CQlCSVQoNikKKwkjZGVmaW5lIENPRVJDUjBfUlhJQ1Y2CQlCSVQoNykKKworCSNkZWZpbmUgQ09F UkNSMF9SWFRDUFY2CQlCSVQoOCkKKwkjZGVmaW5lIENPRVJDUjBfUlhVRFBWNgkJQklUKDkpCisJ I2RlZmluZSBDT0VSQ1IwX1JYSUNNVjYJCUJJVCgxMCkKKwkjZGVmaW5lIENPRVJDUjBfUlhJR01W NgkJQklUKDExKQorCSNkZWZpbmUgQ09FUkNSMF9SWElDVjZWNglCSVQoMTIpCisKKwkjZGVmaW5l IENPRVJDUjBfREVGQVVMVAkJKENPRVJDUjBfUlhJUENFIHwgQ09FUkNSMF9SWFY2UEUgfCBcCisJ CQkJCSBDT0VSQ1IwX1JYVENQRSB8IENPRVJDUjBfUlhVRFBFIHwgXAorCQkJCQkgQ09FUkNSMF9S WFRDUFY2IHwgQ09FUkNSMF9SWFVEUFY2KQorI2RlZmluZSBQNF9DT0VSQ1IxCSgweDk0KQorCSNk ZWZpbmUgQ09FUkNSMV9JUENFRFAJCUJJVCgwKQorCSNkZWZpbmUgQ09FUkNSMV9JUFZFRFAJCUJJ VCgxKQorCSNkZWZpbmUgQ09FUkNSMV9WNlZFRFAJCUJJVCgyKQorCSNkZWZpbmUgQ09FUkNSMV9U Q1BFRFAJCUJJVCgzKQorCSNkZWZpbmUgQ09FUkNSMV9VRFBFRFAJCUJJVCg0KQorCSNkZWZpbmUg Q09FUkNSMV9JQ01QRFAJCUJJVCg1KQorCSNkZWZpbmUgQ09FUkNSMV9JR01QRFAJCUJJVCg2KQor CSNkZWZpbmUgQ09FUkNSMV9JQ1Y2RFAJCUJJVCg3KQorCSNkZWZpbmUgQ09FUkNSMV9SWDY0VEUJ CUJJVCg4KQorCSNkZWZpbmUgQ09FUkNSMV9SWFBQUEUJCUJJVCg5KQorCSNkZWZpbmUgQ09FUkNS MV9UQ1A2RFAJCUJJVCgxMCkKKwkjZGVmaW5lIENPRVJDUjFfVURQNkRQCQlCSVQoMTEpCisJI2Rl ZmluZSBDT0VSQ1IxX0lDNkRQCQlCSVQoMTIpCisJI2RlZmluZSBDT0VSQ1IxX0lHNkRQCQlCSVQo MTMpCisJI2RlZmluZSBDT0VSQ1IxX0lDVjY2RFAJCUJJVCgxNCkKKwkjZGVmaW5lIENPRVJDUjFf UlBDRQkJQklUKDE1KQorCisJI2RlZmluZSBDT0VSQ1IxX0RFRkFVTFQJCShDT0VSQ1IxX1JYUFBQ RSkKKworI2RlZmluZSBQNF9DT0VUQ1IwCSgweDk2KQorCSNkZWZpbmUgQ09FVENSMF9UWElQCQlC SVQoMCkKKwkjZGVmaW5lIENPRVRDUjBfVFhUQ1AJCUJJVCgxKQorCSNkZWZpbmUgQ09FVENSMF9U WFVEUAkJQklUKDIpCisJI2RlZmluZSBDT0VUQ1IwX1RYSUNNUAkJQklUKDMpCisJI2RlZmluZSBD T0VUQ1IwX1RYSUdNUAkJQklUKDQpCisJI2RlZmluZSBDT0VUQ1IwX1RYSUNWNgkJQklUKDUpCisJ I2RlZmluZSBDT0VUQ1IwX1RYVENQVjYJCUJJVCg4KQorCSNkZWZpbmUgQ09FVENSMF9UWFVEUFY2 CQlCSVQoOSkKKwkjZGVmaW5lIENPRVRDUjBfVFhJQ01WNgkJQklUKDEwKQorCSNkZWZpbmUgQ09F VENSMF9UWElHTVY2CQlCSVQoMTEpCisJI2RlZmluZSBDT0VUQ1IwX1RYSUNWNlY2CUJJVCgxMikK KworCSNkZWZpbmUgQ09FVENSMF9ERUZBVUxUCQkoQ09FVENSMF9UWElQIHwgQ09FVENSMF9UWFRD UCB8IFwKKwkJCQkJIENPRVRDUjBfVFhVRFAgfCBDT0VUQ1IwX1RYVENQVjYgfCBcCisJCQkJCSBD T0VUQ1IwX1RYVURQVjYpCisjZGVmaW5lIFA0X0NPRVRDUjEJKDB4OTgpCisJI2RlZmluZSBDT0VU Q1IxX1RYNjRURQkJQklUKDApCisJI2RlZmluZSBDT0VUQ1IxX1RYUFBQRQkJQklUKDEpCisKKyNk ZWZpbmUgUDRfQ09FQ0VEUgkoMHg5QSkKKyNkZWZpbmUgUDRfTDJDRUNSCSgweDlDKQorCisJLyog RGVmaW5pdGlvbiBvZiBQQUdFNSAqLworI2RlZmluZSBQNV9XRlRSCQkoMHhBMikKKwkjZGVmaW5l IFdGVFJfMk1TCQkoMHgwMSkKKwkjZGVmaW5lIFdGVFJfNE1TCQkoMHgwMikKKwkjZGVmaW5lIFdG VFJfOE1TCQkoMHgwMykKKwkjZGVmaW5lIFdGVFJfMTZNUwkJKDB4MDQpCisJI2RlZmluZSBXRlRS XzMyTVMJCSgweDA1KQorCSNkZWZpbmUgV0ZUUl82NE1TCQkoMHgwNikKKwkjZGVmaW5lIFdGVFJf MTI4TVMJCSgweDA3KQorCSNkZWZpbmUgV0ZUUl8yNTZNUwkJKDB4MDgpCisJI2RlZmluZSBXRlRS XzUxMk1TCQkoMHgwOSkKKwkjZGVmaW5lIFdGVFJfMTAyNE1TCQkoMHgwQSkKKwkjZGVmaW5lIFdG VFJfMjA0OE1TCQkoMHgwQikKKwkjZGVmaW5lIFdGVFJfNDA5Nk1TCQkoMHgwQykKKwkjZGVmaW5l IFdGVFJfODE5Mk1TCQkoMHgwRCkKKwkjZGVmaW5lIFdGVFJfMTYzODRNUwkJKDB4MEUpCisJI2Rl ZmluZSBXRlRSXzMyNzY4TVMJCSgweDBGKQorI2RlZmluZSBQNV9XRkNDUgkoMHhBNCkKKyNkZWZp bmUgUDVfV0ZDUjAzCSgweEE2KQorCSNkZWZpbmUgV0ZDUjAzX0YwX0VOCQlCSVQoMCkKKwkjZGVm aW5lIFdGQ1IwM19GMV9FTgkJQklUKDQpCisJI2RlZmluZSBXRkNSMDNfRjJfRU4JCUJJVCg4KQor CSNkZWZpbmUgV0ZDUjAzX0YzX0VOCQlCSVQoMTIpCisjZGVmaW5lIFA1X1dGQ1I0NwkoMHhBOCkK KwkjZGVmaW5lIFdGQ1I0N19GNF9FTgkJQklUKDApCisJI2RlZmluZSBXRkNSNDdfRjVfRU4JCUJJ VCg0KQorCSNkZWZpbmUgV0ZDUjQ3X0Y2X0VOCQlCSVQoOCkKKwkjZGVmaW5lIFdGQ1I0N19GN19F TgkJQklUKDEyKQorI2RlZmluZSBQNV9XRjBCTVIwCSgweEFBKQorI2RlZmluZSBQNV9XRjBCTVIx CSgweEFDKQorI2RlZmluZSBQNV9XRjBDUgkoMHhBRSkKKyNkZWZpbmUgUDVfV0YwT0JSCSgweEIw KQorI2RlZmluZSBQNV9XRjFCTVIwCSgweEIyKQorI2RlZmluZSBQNV9XRjFCTVIxCSgweEI0KQor I2RlZmluZSBQNV9XRjFDUgkoMHhCNikKKyNkZWZpbmUgUDVfV0YxT0JSCSgweEI4KQorI2RlZmlu ZSBQNV9XRjJCTVIwCSgweEJBKQorI2RlZmluZSBQNV9XRjJCTVIxCSgweEJDKQorCisJLyogRGVm aW5pdGlvbiBvZiBQQUdFNiAqLworI2RlZmluZSBQNl9XRjJDUgkoMHhDMikKKyNkZWZpbmUgUDZf V0YyT0JSCSgweEM0KQorI2RlZmluZSBQNl9XRjNCTVIwCSgweEM2KQorI2RlZmluZSBQNl9XRjNC TVIxCSgweEM4KQorI2RlZmluZSBQNl9XRjNDUgkoMHhDQSkKKyNkZWZpbmUgUDZfV0YzT0JSCSgw eENDKQorI2RlZmluZSBQNl9XRjRCTVIwCSgweENFKQorI2RlZmluZSBQNl9XRjRCTVIxCSgweEQw KQorI2RlZmluZSBQNl9XRjRDUgkoMHhEMikKKyNkZWZpbmUgUDZfV0Y0T0JSCSgweEQ0KQorI2Rl ZmluZSBQNl9XRjVCTVIwCSgweEQ2KQorI2RlZmluZSBQNl9XRjVCTVIxCSgweEQ4KQorI2RlZmlu ZSBQNl9XRjVDUgkoMHhEQSkKKyNkZWZpbmUgUDZfV0Y1T0JSCSgweERDKQorCisvKiBEZWZpbml0 aW9uIG9mIFBBR0U3ICovCisjZGVmaW5lIFA3X1dGNkJNUjAJKDB4RTIpCisjZGVmaW5lIFA3X1dG NkJNUjEJKDB4RTQpCisjZGVmaW5lIFA3X1dGNkNSCSgweEU2KQorI2RlZmluZSBQN19XRjZPQlIJ KDB4RTgpCisjZGVmaW5lIFA3X1dGN0JNUjAJKDB4RUEpCisjZGVmaW5lIFA3X1dGN0JNUjEJKDB4 RUMpCisjZGVmaW5lIFA3X1dGN0NSCSgweEVFKQorI2RlZmluZSBQN19XRjdPQlIJKDB4RjApCisj ZGVmaW5lIFA3X1dGUjAxCSgweEYyKQorI2RlZmluZSBQN19XRlIyMwkoMHhGNCkKKyNkZWZpbmUg UDdfV0ZSNDUJKDB4RjYpCisjZGVmaW5lIFA3X1dGUjY3CSgweEY4KQorI2RlZmluZSBQN19XRlBD MAkoMHhGQSkKKyNkZWZpbmUgUDdfV0ZQQzEJKDB4RkMpCisKKy8qIFR4IGhlYWRlcnMgc3RydWN0 dXJlICovCitzdHJ1Y3QgdHhfc29wX2hlYWRlciB7CisJLyogYml0IDE1LTExOiBmbGFncywgYml0 IDEwLTA6IHBhY2tldCBsZW5ndGggKi8KKwl1MTYgZmxhZ3NfbGVuOworCS8qIGJpdCAxNS0xMTog c2VxdWVuY2UgbnVtYmVyLCBiaXQgMTEtMDogcGFja2V0IGxlbmd0aCBiYXIgKi8KKwl1MTYgc2Vx X2xlbmJhcjsKK307CisKK3N0cnVjdCB0eF9zZWdtZW50X2hlYWRlciB7CisJLyogYml0IDE1LTE0 OiBmbGFncywgYml0IDEzLTExOiBzZWdtZW50IG51bWJlciAqLworCS8qIGJpdCAxMC0wOiBzZWdt ZW50IGxlbmd0aCAqLworCXUxNiBmbGFnc19zZXFudW1fc2VnbGVuOworCS8qIGJpdCAxNS0xNDog ZW5kIG9mZnNldCwgYml0IDEzLTExOiBzdGFydCBvZmZzZXQgKi8KKwkvKiBiaXQgMTAtMDogc2Vn bWVudCBsZW5ndGggYmFyICovCisJdTE2IGVvX3NvX3NlZ2xlbmJhcjsKK307CisKK3N0cnVjdCB0 eF9lb3BfaGVhZGVyIHsKKwkvKiBiaXQgMTUtMTE6IHNlcXVlbmNlIG51bWJlciwgYml0IDEwLTA6 IHBhY2tldCBsZW5ndGggKi8KKwl1MTYgc2VxX2xlbjsKKwkvKiBiaXQgMTUtMTE6IHNlcXVlbmNl IG51bWJlciBiYXIsIGJpdCAxMC0wOiBwYWNrZXQgbGVuZ3RoIGJhciAqLworCXUxNiBzZXFiYXJf bGVuYmFyOworfTsKKworc3RydWN0IHR4X3BrdF9pbmZvIHsKKwlzdHJ1Y3QgdHhfc29wX2hlYWRl ciBzb3A7CisJc3RydWN0IHR4X3NlZ21lbnRfaGVhZGVyIHNlZzsKKwlzdHJ1Y3QgdHhfZW9wX2hl YWRlciBlb3A7CisJdTE2IHBrdF9sZW47CisJdTE2IHNlcV9udW07Cit9OworCisvKiBSeCBoZWFk ZXJzIHN0cnVjdHVyZSAqLworc3RydWN0IHJ4X2hlYWRlciB7CisJdTE2IGZsYWdzX2xlbjsKKwl1 MTYgc2VxX2xlbmJhcjsKKwl1MTYgZmxhZ3M7Cit9OworCitleHRlcm4gdW5zaWduZWQgbG9uZyBh eDg4Nzk2Y19ub19yZWdzX21hc2tbXTsKKworI2VuZGlmIC8qICNpZm5kZWYgX0FYODg3OTZDX01B SU5fSCAqLwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2Y19z cGkuYyBiL2RyaXZlcnMvbmV0L2V0aGVybmV0L2FzaXgvYXg4ODc5NmNfc3BpLmMKbmV3IGZpbGUg bW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4xMjUyYTk3ZDFjNTIKLS0tIC9kZXYvbnVs bAorKysgYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZjX3NwaS5jCkBAIC0wLDAg KzEsMTE1IEBACisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5CisvKgor ICogQ29weXJpZ2h0IChjKSAyMDEwIEFTSVggRWxlY3Ryb25pY3MgQ29ycG9yYXRpb24KKyAqIENv cHlyaWdodCAoYykgMjAyMCBTYW1zdW5nIEVsZWN0cm9uaWNzIENvLiwgTHRkLgorICoKKyAqIEFT SVggQVg4ODc5NkMgU1BJIEZhc3QgRXRoZXJuZXQgTGludXggZHJpdmVyCisgKi8KKworI2RlZmlu ZSBwcl9mbXQoZm10KQkiYXg4ODc5NmM6ICIgZm10CisKKyNpbmNsdWRlIDxsaW51eC9zdHJpbmcu aD4KKyNpbmNsdWRlIDxsaW51eC9zcGkvc3BpLmg+CisKKyNpbmNsdWRlICJheDg4Nzk2Y19zcGku aCIKKworY29uc3QgdTggYXg4ODc5NmNfcnhfY21kX2J1Zls1XSA9IHtBWF9TUElDTURfUkVBRF9S WFEsIDB4RkYsIDB4RkYsIDB4RkYsIDB4RkZ9OworY29uc3QgdTggYXg4ODc5NmNfdHhfY21kX2J1 Zls0XSA9IHtBWF9TUElDTURfV1JJVEVfVFhRLCAweEZGLCAweEZGLCAweEZGfTsKKworLyogZHJp dmVyIGJ1cyBtYW5hZ2VtZW50IGZ1bmN0aW9ucyAqLworaW50IGF4c3BpX3dha2V1cChzdHJ1Y3Qg YXhzcGlfZGF0YSAqYXhfc3BpKQoreworCWludCByZXQ7CisKKwlheF9zcGktPmNtZF9idWZbMF0g PSBBWF9TUElDTURfRVhJVF9QV0Q7CS8qIE9QICovCisJcmV0ID0gc3BpX3dyaXRlKGF4X3NwaS0+ c3BpLCBheF9zcGktPmNtZF9idWYsIDEpOworCWlmIChyZXQpCisJCWRldl9lcnIoJmF4X3NwaS0+ c3BpLT5kZXYsICIlcygpIGZhaWxlZDogcmV0ID0gJWRcbiIsIF9fZnVuY19fLCByZXQpOworCXJl dHVybiByZXQ7Cit9CisKK2ludCBheHNwaV9yZWFkX3N0YXR1cyhzdHJ1Y3QgYXhzcGlfZGF0YSAq YXhfc3BpLCBzdHJ1Y3Qgc3BpX3N0YXR1cyAqc3RhdHVzKQoreworCWludCByZXQ7CisKKwkvKiBP UCAqLworCWF4X3NwaS0+Y21kX2J1ZlswXSA9IEFYX1NQSUNNRF9SRUFEX1NUQVRVUzsKKwlyZXQg PSBzcGlfd3JpdGVfdGhlbl9yZWFkKGF4X3NwaS0+c3BpLCBheF9zcGktPmNtZF9idWYsIDEsICh1 OCAqKSZzdGF0dXMsIDMpOworCWlmIChyZXQpCisJCWRldl9lcnIoJmF4X3NwaS0+c3BpLT5kZXYs ICIlcygpIGZhaWxlZDogcmV0ID0gJWRcbiIsIF9fZnVuY19fLCByZXQpOworCWVsc2UKKwkJbGUx Nl90b19jcHVzKCZzdGF0dXMtPmlzcik7CisKKwlyZXR1cm4gcmV0OworfQorCitpbnQgYXhzcGlf cmVhZF9yeHEoc3RydWN0IGF4c3BpX2RhdGEgKmF4X3NwaSwgdm9pZCAqZGF0YSwgaW50IGxlbikK K3sKKwlzdHJ1Y3Qgc3BpX3RyYW5zZmVyICp4ZmVyID0gYXhfc3BpLT5zcGlfcnhfeGZlcjsKKwlp bnQgcmV0OworCisJbWVtY3B5KGF4X3NwaS0+Y21kX2J1ZiwgYXg4ODc5NmNfcnhfY21kX2J1Ziwg NSk7CisKKwl4ZmVyLT50eF9idWYgPSBheF9zcGktPmNtZF9idWY7CisJeGZlci0+cnhfYnVmID0g TlVMTDsKKwl4ZmVyLT5sZW4gPSBheF9zcGktPmNvbXAgPyAyIDogNTsKKwl4ZmVyLT5iaXRzX3Bl cl93b3JkID0gODsKKwlzcGlfbWVzc2FnZV9hZGRfdGFpbCh4ZmVyLCAmYXhfc3BpLT5yeF9tc2cp OworCisJeGZlcisrOworCXhmZXItPnJ4X2J1ZiA9IGRhdGE7CisJeGZlci0+dHhfYnVmID0gTlVM TDsKKwl4ZmVyLT5sZW4gPSBsZW47CisJeGZlci0+Yml0c19wZXJfd29yZCA9IDg7CisJc3BpX21l c3NhZ2VfYWRkX3RhaWwoeGZlciwgJmF4X3NwaS0+cnhfbXNnKTsKKwlyZXQgPSBzcGlfc3luYyhh eF9zcGktPnNwaSwgJmF4X3NwaS0+cnhfbXNnKTsKKwlpZiAocmV0KQorCQlkZXZfZXJyKCZheF9z cGktPnNwaS0+ZGV2LCAiJXMoKSBmYWlsZWQ6IHJldCA9ICVkXG4iLCBfX2Z1bmNfXywgcmV0KTsK KworCXJldHVybiByZXQ7Cit9CisKK2ludCBheHNwaV93cml0ZV90eHEoY29uc3Qgc3RydWN0IGF4 c3BpX2RhdGEgKmF4X3NwaSwgdm9pZCAqZGF0YSwgaW50IGxlbikKK3sKKwlyZXR1cm4gc3BpX3dy aXRlKGF4X3NwaS0+c3BpLCBkYXRhLCBsZW4pOworfQorCit1MTYgYXhzcGlfcmVhZF9yZWcoc3Ry dWN0IGF4c3BpX2RhdGEgKmF4X3NwaSwgdTggcmVnKQoreworCWludCByZXQ7CisJaW50IGxlbiA9 IGF4X3NwaS0+Y29tcCA/IDMgOiA0OworCisJYXhfc3BpLT5jbWRfYnVmWzBdID0gMHgwMzsJLyog T1AgY29kZSByZWFkIHJlZ2lzdGVyICovCisJYXhfc3BpLT5jbWRfYnVmWzFdID0gcmVnOwkvKiBy ZWdpc3RlciBhZGRyZXNzICovCisJYXhfc3BpLT5jbWRfYnVmWzJdID0gMHhGRjsJLyogZHVteSBj eWNsZSAqLworCWF4X3NwaS0+Y21kX2J1ZlszXSA9IDB4RkY7CS8qIGR1bXkgY3ljbGUgKi8KKwly ZXQgPSBzcGlfd3JpdGVfdGhlbl9yZWFkKGF4X3NwaS0+c3BpLAorCQkJCSAgYXhfc3BpLT5jbWRf YnVmLCBsZW4sCisJCQkJICBheF9zcGktPnJ4X2J1ZiwgMik7CisJaWYgKHJldCkgeworCQlkZXZf ZXJyKCZheF9zcGktPnNwaS0+ZGV2LAorCQkJIiVzKCkgZmFpbGVkOiByZXQgPSAlZFxuIiwgX19m dW5jX18sIHJldCk7CisJCXJldHVybiAweEZGRkY7CisJfQorCisJbGUxNl90b19jcHVzKGF4X3Nw aS0+cnhfYnVmKTsKKworCXJldHVybiAqKHUxNiAqKWF4X3NwaS0+cnhfYnVmOworfQorCitpbnQg YXhzcGlfd3JpdGVfcmVnKHN0cnVjdCBheHNwaV9kYXRhICpheF9zcGksIHU4IHJlZywgdTE2IHZh bHVlKQoreworCWludCByZXQ7CisKKwltZW1zZXQoYXhfc3BpLT5jbWRfYnVmLCAwLCBzaXplb2Yo YXhfc3BpLT5jbWRfYnVmKSk7CisJYXhfc3BpLT5jbWRfYnVmWzBdID0gQVhfU1BJQ01EX1dSSVRF X1JFRzsJLyogT1AgY29kZSByZWFkIHJlZ2lzdGVyICovCisJYXhfc3BpLT5jbWRfYnVmWzFdID0g cmVnOwkJCS8qIHJlZ2lzdGVyIGFkZHJlc3MgKi8KKwlheF9zcGktPmNtZF9idWZbMl0gPSB2YWx1 ZTsKKwlheF9zcGktPmNtZF9idWZbM10gPSB2YWx1ZSA+PiA4OworCisJcmV0ID0gc3BpX3dyaXRl KGF4X3NwaS0+c3BpLCBheF9zcGktPmNtZF9idWYsIDQpOworCWlmIChyZXQpCisJCWRldl9lcnIo JmF4X3NwaS0+c3BpLT5kZXYsICIlcygpIGZhaWxlZDogcmV0ID0gJWRcbiIsIF9fZnVuY19fLCBy ZXQpOworCXJldHVybiByZXQ7Cit9CisKZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L2V0aGVybmV0 L2FzaXgvYXg4ODc5NmNfc3BpLmggYi9kcml2ZXJzL25ldC9ldGhlcm5ldC9hc2l4L2F4ODg3OTZj X3NwaS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uNWJjZjkxZjYw M2ZiCi0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9uZXQvZXRoZXJuZXQvYXNpeC9heDg4Nzk2 Y19zcGkuaApAQCAtMCwwICsxLDY5IEBACisvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BM LTIuMC1vbmx5ICovCisvKgorICogQ29weXJpZ2h0IChjKSAyMDEwIEFTSVggRWxlY3Ryb25pY3Mg Q29ycG9yYXRpb24KKyAqIENvcHlyaWdodCAoYykgMjAyMCBTYW1zdW5nIEVsZWN0cm9uaWNzIENv LiwgTHRkLgorICoKKyAqIEFTSVggQVg4ODc5NkMgU1BJIEZhc3QgRXRoZXJuZXQgTGludXggZHJp dmVyCisgKi8KKworI2lmbmRlZiBfQVg4ODc5NkNfU1BJX0gKKyNkZWZpbmUgX0FYODg3OTZDX1NQ SV9ICisKKyNpbmNsdWRlIDxsaW51eC9zcGkvc3BpLmg+CisjaW5jbHVkZSA8bGludXgvdHlwZXMu aD4KKworLyogRGVmaW5pdGlvbiBvZiBTUEkgY29tbWFuZCAqLworI2RlZmluZSBBWF9TUElDTURf V1JJVEVfVFhRCQkweDAyCisjZGVmaW5lIEFYX1NQSUNNRF9SRUFEX1JFRwkJMHgwMworI2RlZmlu ZSBBWF9TUElDTURfUkVBRF9TVEFUVVMJCTB4MDUKKyNkZWZpbmUgQVhfU1BJQ01EX1JFQURfUlhR CQkweDBCCisjZGVmaW5lIEFYX1NQSUNNRF9CSURJUl9XUlEJCTB4QjIKKyNkZWZpbmUgQVhfU1BJ Q01EX1dSSVRFX1JFRwkJMHhEOAorI2RlZmluZSBBWF9TUElDTURfRVhJVF9QV0QJCTB4QUIKKwor ZXh0ZXJuIGNvbnN0IHU4IGF4ODg3OTZjX3J4X2NtZF9idWZbXTsKK2V4dGVybiBjb25zdCB1OCBh eDg4Nzk2Y190eF9jbWRfYnVmW107CisKK3N0cnVjdCBheHNwaV9kYXRhIHsKKwlzdHJ1Y3Qgc3Bp X2RldmljZQkqc3BpOworCXN0cnVjdCBzcGlfbWVzc2FnZQlyeF9tc2c7CisJc3RydWN0IHNwaV90 cmFuc2ZlcglzcGlfcnhfeGZlclsyXTsKKwl1OAkJCWNtZF9idWZbNl07CisJdTgJCQlyeF9idWZb Nl07CisJdTgJCQljb21wOworfTsKKworc3RydWN0IHNwaV9zdGF0dXMgeworCXUxNiBpc3I7CisJ dTggc3RhdHVzOworIwlkZWZpbmUgQVhfU1RBVFVTX1JFQURZCQkweDgwCit9OworCitpbnQgYXhz cGlfcmVhZF9yeHEoc3RydWN0IGF4c3BpX2RhdGEgKmF4X3NwaSwgdm9pZCAqZGF0YSwgaW50IGxl bik7CitpbnQgYXhzcGlfd3JpdGVfdHhxKGNvbnN0IHN0cnVjdCBheHNwaV9kYXRhICpheF9zcGks IHZvaWQgKmRhdGEsIGludCBsZW4pOwordTE2IGF4c3BpX3JlYWRfcmVnKHN0cnVjdCBheHNwaV9k YXRhICpheF9zcGksIHU4IHJlZyk7CitpbnQgYXhzcGlfd3JpdGVfcmVnKHN0cnVjdCBheHNwaV9k YXRhICpheF9zcGksIHU4IHJlZywgdTE2IHZhbHVlKTsKK2ludCBheHNwaV9yZWFkX3N0YXR1cyhz dHJ1Y3QgYXhzcGlfZGF0YSAqYXhfc3BpLCBzdHJ1Y3Qgc3BpX3N0YXR1cyAqc3RhdHVzKTsKK2lu dCBheHNwaV93YWtldXAoc3RydWN0IGF4c3BpX2RhdGEgKmF4X3NwaSk7CisKK3N0YXRpYyBpbmxp bmUgdTE2IEFYX1JFQUQoc3RydWN0IGF4c3BpX2RhdGEgKmF4X3NwaSwgdTggb2Zmc2V0KQorewor CXJldHVybiBheHNwaV9yZWFkX3JlZyhheF9zcGksIG9mZnNldCk7Cit9CisKK3N0YXRpYyBpbmxp bmUgaW50IEFYX1dSSVRFKHN0cnVjdCBheHNwaV9kYXRhICpheF9zcGksIHUxNiB2YWx1ZSwgdTgg b2Zmc2V0KQoreworCXJldHVybiBheHNwaV93cml0ZV9yZWcoYXhfc3BpLCBvZmZzZXQsIHZhbHVl KTsKK30KKworc3RhdGljIGlubGluZSBpbnQgQVhfUkVBRF9TVEFUVVMoc3RydWN0IGF4c3BpX2Rh dGEgKmF4X3NwaSwKKwkJCQkgc3RydWN0IHNwaV9zdGF0dXMgKnN0YXR1cykKK3sKKwlyZXR1cm4g YXhzcGlfcmVhZF9zdGF0dXMoYXhfc3BpLCBzdGF0dXMpOworfQorCitzdGF0aWMgaW5saW5lIGlu dCBBWF9XQUtFVVAoc3RydWN0IGF4c3BpX2RhdGEgKmF4X3NwaSkKK3sKKwlyZXR1cm4gYXhzcGlf d2FrZXVwKGF4X3NwaSk7Cit9CisjZW5kaWYKLS0gCjIuMjYuMgoKCl9fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBs aXN0CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5m cmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK