From nobody Sat Feb 7 18:20:01 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84B4AC54EE9 for ; Tue, 13 Sep 2022 14:24:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233521AbiIMOYn (ORCPT ); Tue, 13 Sep 2022 10:24:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233604AbiIMOXn (ORCPT ); Tue, 13 Sep 2022 10:23:43 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C2D856611C; Tue, 13 Sep 2022 07:15:48 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 83E06614AE; Tue, 13 Sep 2022 14:14:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 87642C433D7; Tue, 13 Sep 2022 14:14:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1663078467; bh=900PzX5Acpk2QwjDYmAp0NBaHR6gsyXB1qRe6hcKIko=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EjYWEr31TSTu/zPUeALnrDL+7bw5+LOX2Er0JtKNy3pVUchTsRc+n/3o1oUlOPN2K Xf6S4TYMTZPUWDKQTzYOa7kM6mO2oOiuD9TxUwIyDzSIatXrHUfxgt8Jib8PmHdJ7q 9FNojrCxKDdWvD+MKAWViMrqED9Vsp8Ukz7nrpeQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Arun Ramadoss , Andrew Lunn , Paolo Abeni , Sasha Levin Subject: [PATCH 5.19 150/192] net: phy: lan87xx: change interrupt src of link_up to comm_ready Date: Tue, 13 Sep 2022 16:04:16 +0200 Message-Id: <20220913140417.497196854@linuxfoundation.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220913140410.043243217@linuxfoundation.org> References: <20220913140410.043243217@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Arun Ramadoss [ Upstream commit 5382033a35227c57a349d74752ad2527780159a9 ] Currently phy link up/down interrupt is enabled using the LAN87xx_INTERRUPT_MASK register. In the lan87xx_read_status function, phy link is determined using the T1_MODE_STAT_REG register comm_ready bit. comm_ready bit is set using the loc_rcvr_status & rem_rcvr_status. Whenever the phy link is up, LAN87xx_INTERRUPT_SOURCE link_up bit is set first but comm_ready bit takes some time to set based on local and remote receiver status. As per the current implementation, interrupt is triggered using link_up but the comm_ready bit is still cleared in the read_status function. So, link is always down. Initially tested with the shared interrupt mechanism with switch and internal phy which is working, but after implementing interrupt controller it is not working. It can fixed either by updating the read_status function to read from LAN87XX_INTERRUPT_SOURCE register or enable the interrupt mask for comm_ready bit. But the validation team recommends the use of comm_ready for link detection. This patch fixes by enabling the comm_ready bit for link_up in the LAN87XX_INTERRUPT_MASK_2 register (MISC Bank) and link_down in LAN87xx_INTERRUPT_MASK register. Fixes: 8a1b415d70b7 ("net: phy: added ethtool master-slave configuration su= pport") Signed-off-by: Arun Ramadoss Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20220905152750.5079-1-arun.ramadoss@microch= ip.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/phy/microchip_t1.c | 58 +++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/microchip_t1.c b/drivers/net/phy/microchip_t1.c index d4c93d59bc539..8569a545e0a3f 100644 --- a/drivers/net/phy/microchip_t1.c +++ b/drivers/net/phy/microchip_t1.c @@ -28,12 +28,16 @@ =20 /* Interrupt Source Register */ #define LAN87XX_INTERRUPT_SOURCE (0x18) +#define LAN87XX_INTERRUPT_SOURCE_2 (0x08) =20 /* Interrupt Mask Register */ #define LAN87XX_INTERRUPT_MASK (0x19) #define LAN87XX_MASK_LINK_UP (0x0004) #define LAN87XX_MASK_LINK_DOWN (0x0002) =20 +#define LAN87XX_INTERRUPT_MASK_2 (0x09) +#define LAN87XX_MASK_COMM_RDY BIT(10) + /* MISC Control 1 Register */ #define LAN87XX_CTRL_1 (0x11) #define LAN87XX_MASK_RGMII_TXC_DLY_EN (0x4000) @@ -424,17 +428,55 @@ static int lan87xx_phy_config_intr(struct phy_device = *phydev) int rc, val =3D 0; =20 if (phydev->interrupts =3D=3D PHY_INTERRUPT_ENABLED) { - /* unmask all source and clear them before enable */ - rc =3D phy_write(phydev, LAN87XX_INTERRUPT_MASK, 0x7FFF); + /* clear all interrupt */ + rc =3D phy_write(phydev, LAN87XX_INTERRUPT_MASK, val); + if (rc < 0) + return rc; + rc =3D phy_read(phydev, LAN87XX_INTERRUPT_SOURCE); - val =3D LAN87XX_MASK_LINK_UP | LAN87XX_MASK_LINK_DOWN; + if (rc < 0) + return rc; + + rc =3D access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, + PHYACC_ATTR_BANK_MISC, + LAN87XX_INTERRUPT_MASK_2, val); + if (rc < 0) + return rc; + + rc =3D access_ereg(phydev, PHYACC_ATTR_MODE_READ, + PHYACC_ATTR_BANK_MISC, + LAN87XX_INTERRUPT_SOURCE_2, 0); + if (rc < 0) + return rc; + + /* enable link down and comm ready interrupt */ + val =3D LAN87XX_MASK_LINK_DOWN; rc =3D phy_write(phydev, LAN87XX_INTERRUPT_MASK, val); + if (rc < 0) + return rc; + + val =3D LAN87XX_MASK_COMM_RDY; + rc =3D access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, + PHYACC_ATTR_BANK_MISC, + LAN87XX_INTERRUPT_MASK_2, val); } else { rc =3D phy_write(phydev, LAN87XX_INTERRUPT_MASK, val); - if (rc) + if (rc < 0) return rc; =20 rc =3D phy_read(phydev, LAN87XX_INTERRUPT_SOURCE); + if (rc < 0) + return rc; + + rc =3D access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, + PHYACC_ATTR_BANK_MISC, + LAN87XX_INTERRUPT_MASK_2, val); + if (rc < 0) + return rc; + + rc =3D access_ereg(phydev, PHYACC_ATTR_MODE_READ, + PHYACC_ATTR_BANK_MISC, + LAN87XX_INTERRUPT_SOURCE_2, 0); } =20 return rc < 0 ? rc : 0; @@ -444,6 +486,14 @@ static irqreturn_t lan87xx_handle_interrupt(struct phy= _device *phydev) { int irq_status; =20 + irq_status =3D access_ereg(phydev, PHYACC_ATTR_MODE_READ, + PHYACC_ATTR_BANK_MISC, + LAN87XX_INTERRUPT_SOURCE_2, 0); + if (irq_status < 0) { + phy_error(phydev); + return IRQ_NONE; + } + irq_status =3D phy_read(phydev, LAN87XX_INTERRUPT_SOURCE); if (irq_status < 0) { phy_error(phydev); --=20 2.35.1