From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.3 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 52EFAC433DF for ; Sun, 9 Aug 2020 23:47:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 095C7206A2 for ; Sun, 9 Aug 2020 23:47:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=vyex.com header.i=@vyex.com header.b="VhRjY12t" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726382AbgHIXrE (ORCPT ); Sun, 9 Aug 2020 19:47:04 -0400 Received: from ns1.vyex.com ([107.150.29.99]:44116 "EHLO ns1.vyex.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726217AbgHIXrD (ORCPT ); Sun, 9 Aug 2020 19:47:03 -0400 X-Greylist: delayed 2789 seconds by postgrey-1.27 at vger.kernel.org; Sun, 09 Aug 2020 19:47:03 EDT DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=vyex.com; s=default; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Date: Message-ID:To:Subject:From:Sender:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=653emjlao6FFneIN+slUveRhlJoYJhZ29TBkBLd+AeU=; b=VhRjY12t194oVoWyZ8rS/RLdLZ 6RNpxhwLQAZEhf4dUBiBtmOj4++xdPY/9MU/xJrsLNO76U3ZNBd92zy6k+FrtEGUX4lRU0V4M63VB yTPCL5AJhd01TixwPd7DIpGDgvDg21hOzOkYbq6xY7cZxMCrSJJqw2dwrX/FoINx0SHThuZf9P6+U rD8PW5JI2fx6DZHXXPXXcRGhYuVx5vBXxG5zftKYgyGGNyUeu6vrhlI9M8FQ1o7hzFYDVnc2/CPx9 lwrZO8ZhfGFUB8VjHrvkPy1tFbgX12bJitgQppQxW6v86oqmWynF+pyoT6/B8HiZ0F2WKsgHrGAOq t+VzoeVg==; Received: from [98.144.109.174] (port=36678 helo=[172.25.22.30]) by echo.vyex.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k4uIr-0002XB-WA for netdev@vger.kernel.org; Sun, 09 Aug 2020 18:00:34 -0500 From: Dave Karr Subject: [RFT PATCH] net: fec: Fix MDIO polled IO To: netdev@vger.kernel.org Message-ID: <813a0ccb-a309-137d-a340-b9b03b9e230c@vyex.com> Date: Sun, 9 Aug 2020 18:00:33 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - echo.vyex.com X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - vyex.com X-Get-Message-Sender-Via: echo.vyex.com: authenticated_id: dkarr@vyex.com X-Authenticated-Sender: echo.vyex.com: dkarr@vyex.com X-Source: X-Source-Args: X-Source-Dir: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Fixes problematic commit f166f890c8f026a931e1bb80f51561a1d2f41b27 Commit broke Ethernet functionality on i.MX53 with 1 GHz clock due to a race condition which may not be observed in the unknown CPU(s) implied by comments to depart from FEC behavior documented by Motorola, Freescale and NXP. During driver initialization the stated intent was to suppress the potential generation of a MII interrupt resulting from a write to MSCR, but for devices which behave as documented, an interrupt is caused by any write to MMFR regardless of value. Testing confirms the i.MX53 behaves as documented. The subsequent attempt to clear any pending MII interrupt generated by either the MMFR or MSCR write is a race condition dependent upon CPU vs. MDC clock speed which permits the interrupt to occur after the write to EIR. Prior to the polled IO patch, regardless of what caused an MII interrupt, the fec_enet_mdio_read/write functions relied upon the interrupt service routine to clear the EIR MII bit and thus the critical region between ISR exit and fec_enet_mdio_read/write entry was small by comparison. Together, this resulted in the subsequent read of PHYID during PHY probing to return before the mdio bus transaction was complete causing invalid data to be read from MMFR which in turn resulted in improper identification of PHY devices on the bus. Fix by eliminating dependency on other functions to clear the EIR MII bit and shrink the critical region by clearing the bit immediately prior to MMFR write within fec_enet_mdio_read/write functions. Remove use of undocumented behavior and replace unconditional reset of MII EIR bit with fec_enet_mdio_wait such that NXP can identify whether regressions noted in 21615efa6a69891fa287bade979d56dd68b09878 and/or 0a699302be5986307b3dcf84ac7a0dd30f9e9305 are due to an intentional write to MMFR with MSCR equal to zero prior to driver initialization, or the result of unpublished or unrealized FEC errata. Reuse FEC_MII_TIMEOUT #define in fec_enet_mdio_wait(). Signed-off-by: Dave Karr --- drivers/net/ethernet/freescale/fec_main.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 9934421814b4..a56169a3b0a9 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1792,7 +1792,7 @@ static int fec_enet_mdio_wait(struct fec_enet_private *fep) int ret; ret = readl_poll_timeout_atomic(fep->hwp + FEC_IEVENT, ievent, - ievent & FEC_ENET_MII, 2, 30000); + ievent & FEC_ENET_MII, 2, FEC_MII_TIMEOUT); if (!ret) writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); @@ -1816,6 +1816,7 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) /* write address */ frame_addr = (regnum >> 16); + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); writel(frame_start | FEC_MMFR_OP_ADDR_WRITE | FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) | FEC_MMFR_TA | (regnum & 0xFFFF), @@ -1838,6 +1839,7 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) } /* start a read op */ + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); writel(frame_start | frame_op | FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) | FEC_MMFR_TA, fep->hwp + FEC_MII_DATA); @@ -1877,6 +1879,7 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, /* write address */ frame_addr = (regnum >> 16); + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); writel(frame_start | FEC_MMFR_OP_ADDR_WRITE | FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) | FEC_MMFR_TA | (regnum & 0xFFFF), @@ -1895,6 +1898,7 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, } /* start a write op */ + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); writel(frame_start | FEC_MMFR_OP_WRITE | FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) | FEC_MMFR_TA | FEC_MMFR_DATA(value), @@ -2114,20 +2118,14 @@ static int fec_enet_mii_init(struct platform_device *pdev) if (suppress_preamble) fep->phy_speed |= BIT(7); - /* Clear MMFR to avoid to generate MII event by writing MSCR. - * MII event generation condition: - * - writing MSCR: - * - mmfr[31:0]_not_zero & mscr[7:0]_is_zero & - * mscr_reg_data_in[7:0] != 0 - * - writing MMFR: - * - mscr[7:0]_not_zero - */ - writel(0, fep->hwp + FEC_MII_DATA); + /* start with mii interrupt flag clear */ + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); /* Clear any pending transaction complete indication */ - writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); + if (!(fec_enet_mdio_wait(fep))) + netdev_dbg(fep->netdev, "MSCR write during init caused mii interrupt\n"); fep->mii_bus = mdiobus_alloc(); if (fep->mii_bus == NULL) { -- 2.26.2