Message ID | 20221202151204.3318592-5-michael@walle.cc |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp916531wrr; Fri, 2 Dec 2022 07:17:12 -0800 (PST) X-Google-Smtp-Source: AA0mqf5pI+U0eyLd7Yomc/BoQQD4YcRFmI26KE26WLpS0y6BRmaqCrh2rj42KhsmJnAMSJIpV3YY X-Received: by 2002:a17:906:d85:b0:7c0:cc5d:e05a with SMTP id m5-20020a1709060d8500b007c0cc5de05amr1566623eji.44.1669994232435; Fri, 02 Dec 2022 07:17:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669994232; cv=none; d=google.com; s=arc-20160816; b=om9hxJA/TXg/8OLmKkINEDBxn5BvS3LyQxJCyb4PQd/OkTW27oN92DA1EreUa5q4Ks OsuQS/GQqp0teap6q1v3xgmsWSytyNK6GSqNhG65bnNBxQPCUlgFgQjx7nGaEduMTr2O Cx/NKdIqkEjphpPAV4tuH6xYPCAKLCHaRf6wJS3B9/KYN2S3qwkakrrYIi16E8bwGRI9 k0Os77oT32uwaTVSNgJl+xXtNZowI1GA9W1Wt/zGnM3Prat+e9j3ZSnI65SiDFobnM03 Az65G/QtixtJ72rmLFprlcehHkT9wSJtjK0lXovISzpA1btaAa5239WLXDkWKJ2YpnCO WPbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=9N5iGN9naDmEHyePTLp/VNDqNAqfYj5SwKQDYp+5n08=; b=SYbUmGvyJbEHP9BwRTVYoAgOnl0PLl0hVX4yXE0h0xgixlPBJhFgb7WDQ61EpkMDT6 Nes9ScxhYta2ZcASX5Lz2aKJfiQG9bs+ZvCkzLJS4LycHB1IukfttiVaLjMHn6ieljrJ vj1BSt2ikzA8qbwlf1cJKkhx7Hu5ysRDfRMtjhAReksoZXVkR1Yqrtrd50bExplS9Ixu Uo9MXQuqWSu7BIqs/1gaLvl6noRgzed1qX/N/xR3fTILnnCW0I7kjwG+AL92YaHHDZK6 Q82k11KK4KArKUkPtUivKcJE3nrkp75zJPSTg9NOxDHcjfCPaP9AsRPstshwnoFYPs8d JGwA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@walle.cc header.s=mail2022082101 header.b=ukgDRQFS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=walle.cc Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s17-20020aa7c551000000b0046c3f90f602si953383edr.600.2022.12.02.07.16.48; Fri, 02 Dec 2022 07:17:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@walle.cc header.s=mail2022082101 header.b=ukgDRQFS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=walle.cc Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233751AbiLBPMa (ORCPT <rfc822;lhua1029@gmail.com> + 99 others); Fri, 2 Dec 2022 10:12:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233332AbiLBPMQ (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 2 Dec 2022 10:12:16 -0500 Received: from mail.3ffe.de (0001.3ffe.de [IPv6:2a01:4f8:c0c:9d57::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 09547A5574; Fri, 2 Dec 2022 07:12:14 -0800 (PST) Received: from mwalle01.kontron.local. (unknown [213.135.10.150]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.3ffe.de (Postfix) with ESMTPSA id BC8662008; Fri, 2 Dec 2022 16:12:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=walle.cc; s=mail2022082101; t=1669993932; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9N5iGN9naDmEHyePTLp/VNDqNAqfYj5SwKQDYp+5n08=; b=ukgDRQFSLv9COkH21ixYjveituhMhPvZ2feOojDvvWOAcpBbwvbMfJ5GanDphDxuiX4MNN e1wKUbMydRsnmvjpgJlWEkEIIKpYntMtawxyOLpesfv7wpKcstyAj7Q5+PTK91rTEhE2pc qQRRQNVk59seNeC6/8zXqYF1jvN0BLMh66VRNbyBJ2wRMHm2dFYzARIWO/E1bm0SipIOt4 agiwA2bA2reTHb80H+vUaZ9ynVC0Ci5jaCMRX30CVx4QD0dsMmc7HvX2bFn3lzWXJN4Bfu 13j7fBYlterynoHWa+2kGIyR1ZiI0a0hikVoJiBljEiQQsgY6Hs4Rn6K6vYbmg== From: Michael Walle <michael@walle.cc> To: Xu Liang <lxu@maxlinear.com>, Andrew Lunn <andrew@lunn.ch>, Heiner Kallweit <hkallweit1@gmail.com>, Russell King <linux@armlinux.org.uk>, "David S . Miller" <davem@davemloft.net>, Eric Dumazet <edumazet@google.com>, Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Rob Herring <robh+dt@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org> Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Michael Walle <michael@walle.cc> Subject: [PATCH net-next v1 4/4] net: phy: mxl-gpy: disable interrupts on GPY215 by default Date: Fri, 2 Dec 2022 16:12:04 +0100 Message-Id: <20221202151204.3318592-5-michael@walle.cc> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221202151204.3318592-1-michael@walle.cc> References: <20221202151204.3318592-1-michael@walle.cc> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam: Yes X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1751115872250528257?= X-GMAIL-MSGID: =?utf-8?q?1751115872250528257?= |
Series |
net: phy: mxl-gpy: broken interrupt fixes
|
|
Commit Message
Michael Walle
Dec. 2, 2022, 3:12 p.m. UTC
The interrupts on the GPY215B and GPY215C are broken and the only viable
fix is to disable them altogether. There is still the possibilty to
opt-in via the device tree.
Signed-off-by: Michael Walle <michael@walle.cc>
---
drivers/net/phy/mxl-gpy.c | 5 +++++
1 file changed, 5 insertions(+)
Comments
On Fri, Dec 02, 2022 at 04:12:04PM +0100, Michael Walle wrote: > The interrupts on the GPY215B and GPY215C are broken and the only viable > fix is to disable them altogether. There is still the possibilty to > opt-in via the device tree. > > Signed-off-by: Michael Walle <michael@walle.cc> > --- > drivers/net/phy/mxl-gpy.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c > index 20e610dda891..edb8cd8313b0 100644 > --- a/drivers/net/phy/mxl-gpy.c > +++ b/drivers/net/phy/mxl-gpy.c > @@ -12,6 +12,7 @@ > #include <linux/mutex.h> > #include <linux/phy.h> > #include <linux/polynomial.h> > +#include <linux/property.h> > #include <linux/netdevice.h> > > /* PHY ID */ > @@ -290,6 +291,10 @@ static int gpy_probe(struct phy_device *phydev) > phydev->priv = priv; > mutex_init(&priv->mbox_lock); > > + if (gpy_has_broken_mdint(phydev) && > + !device_property_present(dev, "maxlinear,use-broken-interrupts")) > + phydev->irq = PHY_POLL; > + I'm not sure of ordering here. It could be phydev->irq is set after probe. The IRQ is requested as part of phy_connect_direct(), which is much later. I think a better place for this test is in gpy_config_intr(), return -EOPNOTSUPP. phy_enable_interrupts() failing should then cause phy_request_interrupt() to use polling. Andrew
Am 2022-12-02 19:42, schrieb Andrew Lunn: > On Fri, Dec 02, 2022 at 04:12:04PM +0100, Michael Walle wrote: >> The interrupts on the GPY215B and GPY215C are broken and the only >> viable >> fix is to disable them altogether. There is still the possibilty to >> opt-in via the device tree. >> >> Signed-off-by: Michael Walle <michael@walle.cc> >> --- >> drivers/net/phy/mxl-gpy.c | 5 +++++ >> 1 file changed, 5 insertions(+) >> >> diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c >> index 20e610dda891..edb8cd8313b0 100644 >> --- a/drivers/net/phy/mxl-gpy.c >> +++ b/drivers/net/phy/mxl-gpy.c >> @@ -12,6 +12,7 @@ >> #include <linux/mutex.h> >> #include <linux/phy.h> >> #include <linux/polynomial.h> >> +#include <linux/property.h> >> #include <linux/netdevice.h> >> >> /* PHY ID */ >> @@ -290,6 +291,10 @@ static int gpy_probe(struct phy_device *phydev) >> phydev->priv = priv; >> mutex_init(&priv->mbox_lock); >> >> + if (gpy_has_broken_mdint(phydev) && >> + !device_property_present(dev, >> "maxlinear,use-broken-interrupts")) >> + phydev->irq = PHY_POLL; >> + > > I'm not sure of ordering here. It could be phydev->irq is set after > probe. The IRQ is requested as part of phy_connect_direct(), which is > much later. I've did it that way, because phy_probe() also sets phydev->irq = PHY_POLL in some cases and the phy driver .probe() is called right after it. > I think a better place for this test is in gpy_config_intr(), return > -EOPNOTSUPP. phy_enable_interrupts() failing should then cause > phy_request_interrupt() to use polling. Which will then print a warning, which might be misleading. Or we disable the warning if -EOPNOTSUPP is returned? -michael
> > > @@ -290,6 +291,10 @@ static int gpy_probe(struct phy_device *phydev) > > > phydev->priv = priv; > > > mutex_init(&priv->mbox_lock); > > > > > > + if (gpy_has_broken_mdint(phydev) && > > > + !device_property_present(dev, > > > "maxlinear,use-broken-interrupts")) > > > + phydev->irq = PHY_POLL; > > > + > > > > I'm not sure of ordering here. It could be phydev->irq is set after > > probe. The IRQ is requested as part of phy_connect_direct(), which is > > much later. > > I've did it that way, because phy_probe() also sets phydev->irq = PHY_POLL > in some cases and the phy driver .probe() is called right after it. Yes, it is a valid point to do this check, but on its own i don't think it is sufficient. > > I think a better place for this test is in gpy_config_intr(), return > > -EOPNOTSUPP. phy_enable_interrupts() failing should then cause > > phy_request_interrupt() to use polling. > > Which will then print a warning, which might be misleading. > Or we disable the warning if -EOPNOTSUPP is returned? Disabling the warning is the right thing to do. Andrew
Am 2022-12-03 21:36, schrieb Andrew Lunn: >> > > @@ -290,6 +291,10 @@ static int gpy_probe(struct phy_device *phydev) >> > > phydev->priv = priv; >> > > mutex_init(&priv->mbox_lock); >> > > >> > > + if (gpy_has_broken_mdint(phydev) && >> > > + !device_property_present(dev, >> > > "maxlinear,use-broken-interrupts")) >> > > + phydev->irq = PHY_POLL; >> > > + >> > >> > I'm not sure of ordering here. It could be phydev->irq is set after >> > probe. The IRQ is requested as part of phy_connect_direct(), which is >> > much later. >> >> I've did it that way, because phy_probe() also sets phydev->irq = >> PHY_POLL >> in some cases and the phy driver .probe() is called right after it. > > Yes, it is a valid point to do this check, but on its own i don't > think it is sufficient. Care to elaborate a bit? E.g. what is the difference to the case the phy would have an interrupt described but no .config_intr() op. >> > I think a better place for this test is in gpy_config_intr(), return >> > -EOPNOTSUPP. phy_enable_interrupts() failing should then cause >> > phy_request_interrupt() to use polling. >> >> Which will then print a warning, which might be misleading. >> Or we disable the warning if -EOPNOTSUPP is returned? > > Disabling the warning is the right thing to do. There is more to this. .config_intr() is also used in phy_init_hw() and phy_drv_supports_irq(). The latter would still return true in our case. I'm not sure that is correct. After trying your suggestion, I'm still in favor of somehow tell the phy core to force polling mode during probe() of the driver. The same way it's done if there is no .config_intr(). It's not like we'd need change the mode after probe during runtime. Also with your proposed changed the attachment print is wrong/misleading as it still prints the original irq instead of PHY_POLL. -michael
> > Yes, it is a valid point to do this check, but on its own i don't > > think it is sufficient. > > Care to elaborate a bit? E.g. what is the difference to the case > the phy would have an interrupt described but no .config_intr() > op. > > > > > I think a better place for this test is in gpy_config_intr(), return > > > > -EOPNOTSUPP. phy_enable_interrupts() failing should then cause > > > > phy_request_interrupt() to use polling. > > > > > > Which will then print a warning, which might be misleading. > > > Or we disable the warning if -EOPNOTSUPP is returned? > > > > Disabling the warning is the right thing to do. > > There is more to this. .config_intr() is also used in > phy_init_hw() and phy_drv_supports_irq(). The latter would > still return true in our case. I'm not sure that is correct. > > After trying your suggestion, I'm still in favor of somehow > tell the phy core to force polling mode during probe() of the > driver. The problem is that the MAC can set the interrupt number after the PHY probe has been called. e.g. https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c#L524 The interrupt needs to be set by the time the PHY is connected to the MAC, which is often in the MAC open method, much later than the PHY probe. Andrew
Am 2022-12-20 14:33, schrieb Andrew Lunn: >> > > > I think a better place for this test is in gpy_config_intr(), return >> > > > -EOPNOTSUPP. phy_enable_interrupts() failing should then cause >> > > > phy_request_interrupt() to use polling. >> > > >> > > Which will then print a warning, which might be misleading. >> > > Or we disable the warning if -EOPNOTSUPP is returned? >> > >> > Disabling the warning is the right thing to do. >> >> There is more to this. .config_intr() is also used in >> phy_init_hw() and phy_drv_supports_irq(). The latter would >> still return true in our case. I'm not sure that is correct. >> >> After trying your suggestion, I'm still in favor of somehow >> tell the phy core to force polling mode during probe() of the >> driver. > > The problem is that the MAC can set the interrupt number after the PHY > probe has been called. e.g. > > https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c#L524 > > The interrupt needs to be set by the time the PHY is connected to the > MAC, which is often in the MAC open method, much later than the PHY > probe. Ok, then phydev->irq should be updated within the phy_attach_direct(). Something like the following: diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index e865be3d7f01..c6c5830f5214 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1537,6 +1537,14 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, phydev->interrupts = PHY_INTERRUPT_DISABLED; + /* PHYs can request to use poll mode even though they have an + * associated interrupt line. This could be the case if they + * detect a broken interrupt handling. + */ + if (phydev->drv->force_polling_mode && + phydev->drv->force_polling_mode(phydev)) + phydev->irq = PHY_POLL; + /* Port is set to PORT_TP by default and the actual PHY driver will set * it to different value depending on the PHY configuration. If we have * the generic PHY driver we can't figure it out, thus set the old That callback could be too specifc, I don't know. We could also have phydev->drv->pre_attach() which then can update the phydev->irq itself. Btw. the phy_attached_info() in the stmmac seems to be a leftover from before the phylink conversion. phylink will print a similar info but when the PHY is actually attached. -michael
diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c index 20e610dda891..edb8cd8313b0 100644 --- a/drivers/net/phy/mxl-gpy.c +++ b/drivers/net/phy/mxl-gpy.c @@ -12,6 +12,7 @@ #include <linux/mutex.h> #include <linux/phy.h> #include <linux/polynomial.h> +#include <linux/property.h> #include <linux/netdevice.h> /* PHY ID */ @@ -290,6 +291,10 @@ static int gpy_probe(struct phy_device *phydev) phydev->priv = priv; mutex_init(&priv->mbox_lock); + if (gpy_has_broken_mdint(phydev) && + !device_property_present(dev, "maxlinear,use-broken-interrupts")) + phydev->irq = PHY_POLL; + fw_version = phy_read(phydev, PHY_FWV); if (fw_version < 0) return fw_version;