Message ID | 20231206-stmmac-no-mdio-node-v2-1-333cae49b1ca@redhat.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp4449319vqy; Wed, 6 Dec 2023 15:46:43 -0800 (PST) X-Google-Smtp-Source: AGHT+IG46eYlcOI9P4AIi6dPIRm6hZBdHBFS/SxWs3LdKDalRclQpBqB4FiVQQeFxc0Iyqqzn3o0 X-Received: by 2002:a05:6a00:299a:b0:6cb:4c84:43ce with SMTP id cj26-20020a056a00299a00b006cb4c8443cemr1992937pfb.34.1701906402954; Wed, 06 Dec 2023 15:46:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701906402; cv=none; d=google.com; s=arc-20160816; b=v+DsFQkFcm+lYyjwTNnpZpQosxp9WvBpQW8RiuAkl92k3of1Fev7K0s4OoCR8hJPX4 wwd4FDT4Hj8ziNSwpFkW80XwtlN+RmlOhGsD0jAMpKULJ+yzfO0QH/8bYQow9xKLAhFr c4lleErSkDJ51ILjcD4A/wS60cYfPXd0+gr5LayJURW8CqVLFi7Ctox0dCG2mgffNdNK vlFbwGzzpPHpQKqNWDG1y9g2gmJJAylmw97e4iLB1yu0nx0M0qAEZ8GVULK98jDSbwo+ sN2t8l7NbrtQwaYshQ83qOl8ABz3dyddXKyvFoo5OAjXBIZRPBcg3hB+WVUqBzk6Ccuv wmSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:message-id:content-transfer-encoding :mime-version:subject:date:from:dkim-signature; bh=8esKVkgkdO38qfOOlPF2GDuWhXzWAxbw0J892C+UC7Y=; fh=e95a1bHSUArKqofcKNnyWBwvTbSBrVSg/GSgZFoUaZg=; b=Zuj2Bpo0V2PXnYmXpLTyZnzDFW1uD9pSmienhj9jza+Oqz5ny5iFnnkqpUUZX1Zye0 7eZJAvH9dh5RKqVEOhXU69v3Cfsvq687MySC9s4Di6aTA3moSkog2JCkHlGT07hnTMl5 epq2zWRSjNYkn85mSAXJnjXmW1A2m6bqyhZLAogyp9/ryMV9s1k4LWF8c83l8GUpIXG8 bf74l4o/qUpBY26uWU5gM4lo7kY0tdt05QECvxe3cS+k0SfE71U1BMVBnwT9AERyMQU+ C5raQmC/xeCXVZLGwk7bD86NNQbXUHoQbBNw0MR7Na08ZdJzOqVdMzqYawEx77fLy2kg +KIQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=gTZVBEzA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id w20-20020a056a0014d400b006cde5241c15si125924pfu.306.2023.12.06.15.46.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Dec 2023 15:46:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=gTZVBEzA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id AA9C080CB161; Wed, 6 Dec 2023 15:46:39 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1441806AbjLFXqR (ORCPT <rfc822;pusanteemu@gmail.com> + 99 others); Wed, 6 Dec 2023 18:46:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230512AbjLFXqQ (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 6 Dec 2023 18:46:16 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C27E122 for <linux-kernel@vger.kernel.org>; Wed, 6 Dec 2023 15:46:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1701906380; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8esKVkgkdO38qfOOlPF2GDuWhXzWAxbw0J892C+UC7Y=; b=gTZVBEzA7eNmgI4iUx3i5yXgZYBlR6AQa1CCVSAJX1XXwQMTnhFHngolz8mg7rKv2G28pL /hCPLquzeSMY7fCeeTJcjtlGcZSVi0KopQxWyoMaWZEHMC6W/cv1WRwQotvn25Bxk2Fz/Y OcBRm9ADIU2MULWQwKQ6BBZ8fsYxG6E= Received: from mail-oo1-f71.google.com (mail-oo1-f71.google.com [209.85.161.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-357-CXa9C8nRO6-uSjN3KEgS1g-1; Wed, 06 Dec 2023 18:46:19 -0500 X-MC-Unique: CXa9C8nRO6-uSjN3KEgS1g-1 Received: by mail-oo1-f71.google.com with SMTP id 006d021491bc7-58dad14ab40so94711eaf.1 for <linux-kernel@vger.kernel.org>; Wed, 06 Dec 2023 15:46:19 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701906378; x=1702511178; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=8esKVkgkdO38qfOOlPF2GDuWhXzWAxbw0J892C+UC7Y=; b=avGKs9GnSs2B1upVnOKs0kbYep0EViNhTj4tGjnuY8+w5IcnWtK0b8ILTaEa/UuhKt 2WcQJ7KT8MKojOfp/X8RUWfhOfhzovneioQGpCwCWzFU4tU5d5bASr8XB5C5I+WZMYsK HqD2xN1RLFC+SOWv8nkMyrODREN4LkpoxVJD7tvGF3ePJes4VPCIABg6u5wN0XGiGpeL nEy2ESzo/agfKy8Etm3DP2bEM3WWjad1vcf+sPaH7GeRZ1k7icN9XT45DDGLpNasBSL2 KnjGbxszcsXWEMrJ0e/QJSOYX8HiA7GfoOLWEwH7DHBZU/eVXRSDUtHTmixChr+AoJ7Y IcVw== X-Gm-Message-State: AOJu0YzZlikXirLVGskj9huVLkJeSq+Hn+kC6/cZlwBRGOAXpuZtJFpK 5KxwKdbwv8ez30JV5OIZ7fLWCmkkGSGcT+WUvFxFpK8BYAmARdt0FMbQLDEqxJvJxFUxEGhzzgX 3eIUdAzxYCDYyAC5ZOk0XzfFFN1CwyCZh X-Received: by 2002:a05:6358:2910:b0:16d:bbb3:69c6 with SMTP id y16-20020a056358291000b0016dbbb369c6mr2398878rwb.13.1701906377933; Wed, 06 Dec 2023 15:46:17 -0800 (PST) X-Received: by 2002:a05:6358:2910:b0:16d:bbb3:69c6 with SMTP id y16-20020a056358291000b0016dbbb369c6mr2398863rwb.13.1701906377591; Wed, 06 Dec 2023 15:46:17 -0800 (PST) Received: from [192.168.1.164] ([2600:1700:1ff0:d0e0::47]) by smtp.gmail.com with ESMTPSA id lg21-20020a056214549500b0067a14238fa9sm11568qvb.94.2023.12.06.15.46.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Dec 2023 15:46:17 -0800 (PST) From: Andrew Halaney <ahalaney@redhat.com> Date: Wed, 06 Dec 2023 17:46:09 -0600 Subject: [PATCH net-next v2] net: stmmac: don't create a MDIO bus if unnecessary MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20231206-stmmac-no-mdio-node-v2-1-333cae49b1ca@redhat.com> X-B4-Tracking: v=1; b=H4sIAMAHcWUC/z2MwQqDMBBEf0X23BU31lY99T9KD9FdNWASSYII4 r839NDTzGOYd0KUYCRCX5wQZDfReJdB3QoYF+1mQcOZQVWqJlJPjMlaPaLzaNn4nCxIPHSsW60 a7iA/tyCTOX7WNzhJ6ORI8MnLFLzFtATRf2vVVi3l0txLokdTI+EQ5vU1zCx7ua1wXV/b0uTPp gAAAA== To: Alexandre Torgue <alexandre.torgue@foss.st.com>, Jose Abreu <joabreu@synopsys.com>, "David S. Miller" <davem@davemloft.net>, Eric Dumazet <edumazet@google.com>, Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Maxime Coquelin <mcoquelin.stm32@gmail.com> Cc: netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski <bartosz.golaszewski@linaro.org>, Andrew Halaney <ahalaney@redhat.com> X-Mailer: b4 0.12.3 X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Wed, 06 Dec 2023 15:46:39 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784578208273001706 X-GMAIL-MSGID: 1784578208273001706 |
Series |
[net-next,v2] net: stmmac: don't create a MDIO bus if unnecessary
|
|
Commit Message
Andrew Halaney
Dec. 6, 2023, 11:46 p.m. UTC
The stmmac_dt_phy() function, which parses the devicetree node of the MAC and ultimately causes MDIO bus allocation, misinterprets what fixed-link means in relation to the MAC's MDIO bus. This results in a MDIO bus being created in situations it need not be. Currently a MDIO bus is created if the description is either: 1. Not fixed-link 2. fixed-link but contains a MDIO bus as well The "1" case above isn't always accurate. If there's a phy-handle, it could be referencing a phy on another MDIO controller's bus[1]. In this case currently the MAC will make a MDIO bus and scan it all anyways unnecessarily. There's also a lot of upstream devicetrees[2] that expect a MDIO bus to be created and scanned for a phy. This case can also be inferred from the platform description by not having a phy-handle && not being fixed-link. This hits case "1" in the current driver's logic. Let's improve the logic to create a MDIO bus if either: - Devicetree contains a MDIO bus - !fixed-link && !phy-handle (legacy handling) Below upstream devicetree snippets can be found that explain some of the cases above more concretely. Here's[0] a devicetree example where the MAC is both fixed-link and driving a switch on MDIO (case "2" above). This needs a MDIO bus to be created: &fec1 { phy-mode = "rmii"; fixed-link { speed = <100>; full-duplex; }; mdio1: mdio { switch0: switch0@0 { compatible = "marvell,mv88e6190"; pinctrl-0 = <&pinctrl_gpio_switch0>; }; }; }; Here's[1] an example where there is no MDIO bus or fixed-link for the ethernet1 MAC, so no MDIO bus should be created since ethernet0 is the MDIO master for ethernet1's phy: ðernet0 { phy-mode = "sgmii"; phy-handle = <&sgmii_phy0>; mdio { compatible = "snps,dwmac-mdio"; sgmii_phy0: phy@8 { compatible = "ethernet-phy-id0141.0dd4"; reg = <0x8>; device_type = "ethernet-phy"; }; sgmii_phy1: phy@a { compatible = "ethernet-phy-id0141.0dd4"; reg = <0xa>; device_type = "ethernet-phy"; }; }; }; ðernet1 { phy-mode = "sgmii"; phy-handle = <&sgmii_phy1>; }; Finally there's descriptions like this[2] which don't describe the MDIO bus but expect it to be created and the whole address space scanned for a phy since there's no phy-handle or fixed-link described: &gmac { phy-supply = <&vcc_lan>; phy-mode = "rmii"; snps,reset-gpio = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>; snps,reset-active-low; snps,reset-delays-us = <0 10000 1000000>; }; [0] https://elixir.bootlin.com/linux/v6.5-rc5/source/arch/arm/boot/dts/nxp/vf/vf610-zii-ssmb-dtu.dts [1] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/qcom/sa8775p-ride.dts [2] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/rockchip/rk3368-r88.dts#L164 Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Signed-off-by: Andrew Halaney <ahalaney@redhat.com> --- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 85 ++++++++++------------ 1 file changed, 37 insertions(+), 48 deletions(-) --- base-commit: fd8a79b63710acb84321be3ce74be23c876873fb change-id: 20231127-stmmac-no-mdio-node-1db9da8a25d9 Best regards,
Comments
On Wed, Dec 06, 2023 at 05:46:09PM -0600, Andrew Halaney wrote: > The stmmac_dt_phy() function, which parses the devicetree node of the > MAC and ultimately causes MDIO bus allocation, misinterprets what > fixed-link means in relation to the MAC's MDIO bus. This results in > a MDIO bus being created in situations it need not be. > > Currently a MDIO bus is created if the description is either: > > 1. Not fixed-link > 2. fixed-link but contains a MDIO bus as well > > The "1" case above isn't always accurate. If there's a phy-handle, > it could be referencing a phy on another MDIO controller's bus[1]. In > this case currently the MAC will make a MDIO bus and scan it all > anyways unnecessarily. > > There's also a lot of upstream devicetrees[2] that expect a MDIO bus to > be created and scanned for a phy. This case can also be inferred from > the platform description by not having a phy-handle && not being > fixed-link. This hits case "1" in the current driver's logic. > > Let's improve the logic to create a MDIO bus if either: > > - Devicetree contains a MDIO bus > - !fixed-link && !phy-handle (legacy handling) > > Below upstream devicetree snippets can be found that explain some of > the cases above more concretely. > > Here's[0] a devicetree example where the MAC is both fixed-link and > driving a switch on MDIO (case "2" above). This needs a MDIO bus to > be created: > > &fec1 { > phy-mode = "rmii"; > > fixed-link { > speed = <100>; > full-duplex; > }; > > mdio1: mdio { > switch0: switch0@0 { > compatible = "marvell,mv88e6190"; > pinctrl-0 = <&pinctrl_gpio_switch0>; > }; > }; > }; > > Here's[1] an example where there is no MDIO bus or fixed-link for > the ethernet1 MAC, so no MDIO bus should be created since ethernet0 > is the MDIO master for ethernet1's phy: > > ðernet0 { > phy-mode = "sgmii"; > phy-handle = <&sgmii_phy0>; > > mdio { > compatible = "snps,dwmac-mdio"; > sgmii_phy0: phy@8 { > compatible = "ethernet-phy-id0141.0dd4"; > reg = <0x8>; > device_type = "ethernet-phy"; > }; > > sgmii_phy1: phy@a { > compatible = "ethernet-phy-id0141.0dd4"; > reg = <0xa>; > device_type = "ethernet-phy"; > }; > }; > }; > > ðernet1 { > phy-mode = "sgmii"; > phy-handle = <&sgmii_phy1>; > }; > > Finally there's descriptions like this[2] which don't describe the > MDIO bus but expect it to be created and the whole address space > scanned for a phy since there's no phy-handle or fixed-link described: > > &gmac { > phy-supply = <&vcc_lan>; > phy-mode = "rmii"; > snps,reset-gpio = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>; > snps,reset-active-low; > snps,reset-delays-us = <0 10000 1000000>; > }; > > [0] https://elixir.bootlin.com/linux/v6.5-rc5/source/arch/arm/boot/dts/nxp/vf/vf610-zii-ssmb-dtu.dts > [1] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/qcom/sa8775p-ride.dts > [2] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/rockchip/rk3368-r88.dts#L164 > > Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > Signed-off-by: Andrew Halaney <ahalaney@redhat.com> > --- Gah, I failed to describe my changes since Bart's v1 when picking this up with b4 to make v2. Whoops! Changes since v1: - Handle the fixed-link + mdio case (Andrew Lunn) - Reworded commit message - Handle the "legacy" case still mentioned in the commit - Bit further refactoring of the function
Hi Andrew On Wed, Dec 06, 2023 at 05:46:09PM -0600, Andrew Halaney wrote: > The stmmac_dt_phy() function, which parses the devicetree node of the > MAC and ultimately causes MDIO bus allocation, misinterprets what > fixed-link means in relation to the MAC's MDIO bus. This results in > a MDIO bus being created in situations it need not be. > > Currently a MDIO bus is created if the description is either: > > 1. Not fixed-link > 2. fixed-link but contains a MDIO bus as well > > The "1" case above isn't always accurate. If there's a phy-handle, > it could be referencing a phy on another MDIO controller's bus[1]. In > this case currently the MAC will make a MDIO bus and scan it all > anyways unnecessarily. > > There's also a lot of upstream devicetrees[2] that expect a MDIO bus to > be created and scanned for a phy. This case can also be inferred from > the platform description by not having a phy-handle && not being > fixed-link. This hits case "1" in the current driver's logic. > > Let's improve the logic to create a MDIO bus if either: > > - Devicetree contains a MDIO bus > - !fixed-link && !phy-handle (legacy handling) > > Below upstream devicetree snippets can be found that explain some of > the cases above more concretely. > > Here's[0] a devicetree example where the MAC is both fixed-link and > driving a switch on MDIO (case "2" above). This needs a MDIO bus to > be created: > > &fec1 { > phy-mode = "rmii"; > > fixed-link { > speed = <100>; > full-duplex; > }; > > mdio1: mdio { > switch0: switch0@0 { > compatible = "marvell,mv88e6190"; > pinctrl-0 = <&pinctrl_gpio_switch0>; > }; > }; > }; > > Here's[1] an example where there is no MDIO bus or fixed-link for > the ethernet1 MAC, so no MDIO bus should be created since ethernet0 > is the MDIO master for ethernet1's phy: > > ðernet0 { > phy-mode = "sgmii"; > phy-handle = <&sgmii_phy0>; > > mdio { > compatible = "snps,dwmac-mdio"; > sgmii_phy0: phy@8 { > compatible = "ethernet-phy-id0141.0dd4"; > reg = <0x8>; > device_type = "ethernet-phy"; > }; > > sgmii_phy1: phy@a { > compatible = "ethernet-phy-id0141.0dd4"; > reg = <0xa>; > device_type = "ethernet-phy"; > }; > }; > }; > > ðernet1 { > phy-mode = "sgmii"; > phy-handle = <&sgmii_phy1>; > }; > > Finally there's descriptions like this[2] which don't describe the > MDIO bus but expect it to be created and the whole address space > scanned for a phy since there's no phy-handle or fixed-link described: > > &gmac { > phy-supply = <&vcc_lan>; > phy-mode = "rmii"; > snps,reset-gpio = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>; > snps,reset-active-low; > snps,reset-delays-us = <0 10000 1000000>; > }; > > [0] https://elixir.bootlin.com/linux/v6.5-rc5/source/arch/arm/boot/dts/nxp/vf/vf610-zii-ssmb-dtu.dts > [1] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/qcom/sa8775p-ride.dts > [2] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/rockchip/rk3368-r88.dts#L164 Thank you for the patch. Please find a comment below. > > Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > Signed-off-by: Andrew Halaney <ahalaney@redhat.com> > --- > .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 85 ++++++++++------------ > 1 file changed, 37 insertions(+), 48 deletions(-) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > index 1ffde555da47..7da461fe93f6 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > @@ -296,69 +296,39 @@ static int stmmac_mtl_setup(struct platform_device *pdev, > } > > /** > - * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources > - * @plat: driver data platform structure > - * @np: device tree node > - * @dev: device pointer > - * Description: > - * The mdio bus will be allocated in case of a phy transceiver is on board; > - * it will be NULL if the fixed-link is configured. > - * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated > - * in any case (for DSA, mdio must be registered even if fixed-link). > - * The table below sums the supported configurations: > - * ------------------------------- > - * snps,phy-addr | Y > - * ------------------------------- > - * phy-handle | Y > - * ------------------------------- > - * fixed-link | N > - * ------------------------------- > - * snps,dwmac-mdio | > - * even if | Y > - * fixed-link | > - * ------------------------------- > + * stmmac_of_get_mdio() - Gets the MDIO bus from the devicetree > + * @np: devicetree node > * > - * It returns 0 in case of success otherwise -ENODEV. > + * The MDIO bus will be searched for in the following ways: > + * 1. The compatible is "snps,dwc-qos-ethernet-4.10" && a "mdio" named > + * child node exists > + * 2. A child node with the "snps,dwmac-mdio" compatible is present > + * > + * Return: The MDIO node if present otherwise NULL > */ > -static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, > - struct device_node *np, struct device *dev) > +static struct device_node *stmmac_of_get_mdio(struct device_node *np) > { > - bool mdio = !of_phy_is_fixed_link(np); > static const struct of_device_id need_mdio_ids[] = { > { .compatible = "snps,dwc-qos-ethernet-4.10" }, > {}, > }; > + struct device_node *mdio_node = NULL; > > if (of_match_node(need_mdio_ids, np)) { > - plat->mdio_node = of_get_child_by_name(np, "mdio"); > + mdio_node = of_get_child_by_name(np, "mdio"); > } else { > /** > * If snps,dwmac-mdio is passed from DT, always register > * the MDIO > */ > - for_each_child_of_node(np, plat->mdio_node) { > - if (of_device_is_compatible(plat->mdio_node, > + for_each_child_of_node(np, mdio_node) { > + if (of_device_is_compatible(mdio_node, > "snps,dwmac-mdio")) > break; > } > } > > - if (plat->mdio_node) { > - dev_dbg(dev, "Found MDIO subnode\n"); > - mdio = true; > - } > - > - if (mdio) { > - plat->mdio_bus_data = > - devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data), > - GFP_KERNEL); > - if (!plat->mdio_bus_data) > - return -ENOMEM; > - > - plat->mdio_bus_data->needs_reset = true; > - } > - > - return 0; > + return mdio_node; > } > > /** > @@ -417,6 +387,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) > struct device_node *np = pdev->dev.of_node; > struct plat_stmmacenet_data *plat; > struct stmmac_dma_cfg *dma_cfg; > + bool legacy_mdio; > int phy_mode; > void *ret; > int rc; > @@ -471,10 +442,28 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) > if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) > dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); > > - /* To Configure PHY by using all device-tree supported properties */ > - rc = stmmac_dt_phy(plat, np, &pdev->dev); > - if (rc) > - return ERR_PTR(rc); > + plat->mdio_node = stmmac_of_get_mdio(np); > + if (plat->mdio_node) > + dev_dbg(&pdev->dev, "Found MDIO subnode\n"); > + > + /* Legacy devicetrees allowed for no MDIO bus description and expect > + * the bus to be scanned for devices. If there's no phy or fixed-link > + * described assume this is the case since there must be something > + * connected to the MAC. > + */ > + legacy_mdio = !of_phy_is_fixed_link(np) && !plat->phy_node; > + if (legacy_mdio) > + dev_info(&pdev->dev, "Deprecated MDIO bus assumption used\n"); > + > + if (plat->mdio_node || legacy_mdio) { > + plat->mdio_bus_data = devm_kzalloc(&pdev->dev, > + sizeof(struct stmmac_mdio_bus_data), > + GFP_KERNEL); > + if (!plat->mdio_bus_data) > + return ERR_PTR(-ENOMEM); > + > + plat->mdio_bus_data->needs_reset = true; > + } Why did you decide to move this out of the dedicated function? stmmac_probe_config_dt() is already overwhelmed with various non-coherent actions. The method has already got to being too long to follow the kernel coding style limit (I have got a not submitted yet cleanup patchset which step-by-step fixes that). Could you please get the chunk above back to the respective function and, for instance, just change it's name to something like stmmac_mdio_setup()? (I prefer having "_setup" suffix because some of the locally defined static methods already use it: stmmac_axi_setup(), stmmac_mtl_setup().) -Serge(y) > > of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size); > > > --- > base-commit: fd8a79b63710acb84321be3ce74be23c876873fb > change-id: 20231127-stmmac-no-mdio-node-1db9da8a25d9 > > Best regards, > -- > Andrew Halaney <ahalaney@redhat.com> > >
On Thu, Dec 07, 2023 at 02:56:25PM +0300, Serge Semin wrote: > Hi Andrew > > On Wed, Dec 06, 2023 at 05:46:09PM -0600, Andrew Halaney wrote: > > The stmmac_dt_phy() function, which parses the devicetree node of the > > MAC and ultimately causes MDIO bus allocation, misinterprets what > > fixed-link means in relation to the MAC's MDIO bus. This results in > > a MDIO bus being created in situations it need not be. > > > > Currently a MDIO bus is created if the description is either: > > > > 1. Not fixed-link > > 2. fixed-link but contains a MDIO bus as well > > > > The "1" case above isn't always accurate. If there's a phy-handle, > > it could be referencing a phy on another MDIO controller's bus[1]. In > > this case currently the MAC will make a MDIO bus and scan it all > > anyways unnecessarily. > > > > There's also a lot of upstream devicetrees[2] that expect a MDIO bus to > > be created and scanned for a phy. This case can also be inferred from > > the platform description by not having a phy-handle && not being > > fixed-link. This hits case "1" in the current driver's logic. > > > > Let's improve the logic to create a MDIO bus if either: > > > > - Devicetree contains a MDIO bus > > - !fixed-link && !phy-handle (legacy handling) > > > > Below upstream devicetree snippets can be found that explain some of > > the cases above more concretely. > > > > Here's[0] a devicetree example where the MAC is both fixed-link and > > driving a switch on MDIO (case "2" above). This needs a MDIO bus to > > be created: > > > > &fec1 { > > phy-mode = "rmii"; > > > > fixed-link { > > speed = <100>; > > full-duplex; > > }; > > > > mdio1: mdio { > > switch0: switch0@0 { > > compatible = "marvell,mv88e6190"; > > pinctrl-0 = <&pinctrl_gpio_switch0>; > > }; > > }; > > }; > > > > Here's[1] an example where there is no MDIO bus or fixed-link for > > the ethernet1 MAC, so no MDIO bus should be created since ethernet0 > > is the MDIO master for ethernet1's phy: > > > > ðernet0 { > > phy-mode = "sgmii"; > > phy-handle = <&sgmii_phy0>; > > > > mdio { > > compatible = "snps,dwmac-mdio"; > > sgmii_phy0: phy@8 { > > compatible = "ethernet-phy-id0141.0dd4"; > > reg = <0x8>; > > device_type = "ethernet-phy"; > > }; > > > > sgmii_phy1: phy@a { > > compatible = "ethernet-phy-id0141.0dd4"; > > reg = <0xa>; > > device_type = "ethernet-phy"; > > }; > > }; > > }; > > > > ðernet1 { > > phy-mode = "sgmii"; > > phy-handle = <&sgmii_phy1>; > > }; > > > > Finally there's descriptions like this[2] which don't describe the > > MDIO bus but expect it to be created and the whole address space > > scanned for a phy since there's no phy-handle or fixed-link described: > > > > &gmac { > > phy-supply = <&vcc_lan>; > > phy-mode = "rmii"; > > snps,reset-gpio = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>; > > snps,reset-active-low; > > snps,reset-delays-us = <0 10000 1000000>; > > }; > > > > [0] https://elixir.bootlin.com/linux/v6.5-rc5/source/arch/arm/boot/dts/nxp/vf/vf610-zii-ssmb-dtu.dts > > [1] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/qcom/sa8775p-ride.dts > > [2] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/rockchip/rk3368-r88.dts#L164 > > Thank you for the patch. Please find a comment below. > > > > > Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > Signed-off-by: Andrew Halaney <ahalaney@redhat.com> > > --- > > .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 85 ++++++++++------------ > > 1 file changed, 37 insertions(+), 48 deletions(-) > > > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > > index 1ffde555da47..7da461fe93f6 100644 > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > > @@ -296,69 +296,39 @@ static int stmmac_mtl_setup(struct platform_device *pdev, > > } > > > > /** > > - * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources > > - * @plat: driver data platform structure > > - * @np: device tree node > > - * @dev: device pointer > > - * Description: > > - * The mdio bus will be allocated in case of a phy transceiver is on board; > > - * it will be NULL if the fixed-link is configured. > > - * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated > > - * in any case (for DSA, mdio must be registered even if fixed-link). > > - * The table below sums the supported configurations: > > - * ------------------------------- > > - * snps,phy-addr | Y > > - * ------------------------------- > > - * phy-handle | Y > > - * ------------------------------- > > - * fixed-link | N > > - * ------------------------------- > > - * snps,dwmac-mdio | > > - * even if | Y > > - * fixed-link | > > - * ------------------------------- > > + * stmmac_of_get_mdio() - Gets the MDIO bus from the devicetree > > + * @np: devicetree node > > * > > - * It returns 0 in case of success otherwise -ENODEV. > > + * The MDIO bus will be searched for in the following ways: > > + * 1. The compatible is "snps,dwc-qos-ethernet-4.10" && a "mdio" named > > + * child node exists > > + * 2. A child node with the "snps,dwmac-mdio" compatible is present > > + * > > + * Return: The MDIO node if present otherwise NULL > > */ > > -static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, > > - struct device_node *np, struct device *dev) > > +static struct device_node *stmmac_of_get_mdio(struct device_node *np) > > { > > - bool mdio = !of_phy_is_fixed_link(np); > > static const struct of_device_id need_mdio_ids[] = { > > { .compatible = "snps,dwc-qos-ethernet-4.10" }, > > {}, > > }; > > + struct device_node *mdio_node = NULL; > > > > if (of_match_node(need_mdio_ids, np)) { > > - plat->mdio_node = of_get_child_by_name(np, "mdio"); > > + mdio_node = of_get_child_by_name(np, "mdio"); > > } else { > > /** > > * If snps,dwmac-mdio is passed from DT, always register > > * the MDIO > > */ > > - for_each_child_of_node(np, plat->mdio_node) { > > - if (of_device_is_compatible(plat->mdio_node, > > + for_each_child_of_node(np, mdio_node) { > > + if (of_device_is_compatible(mdio_node, > > "snps,dwmac-mdio")) > > break; > > } > > } > > > > - if (plat->mdio_node) { > > - dev_dbg(dev, "Found MDIO subnode\n"); > > - mdio = true; > > - } > > - > > - if (mdio) { > > - plat->mdio_bus_data = > > - devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data), > > - GFP_KERNEL); > > - if (!plat->mdio_bus_data) > > - return -ENOMEM; > > - > > - plat->mdio_bus_data->needs_reset = true; > > - } > > - > > - return 0; > > + return mdio_node; > > } > > > > /** > > @@ -417,6 +387,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) > > struct device_node *np = pdev->dev.of_node; > > struct plat_stmmacenet_data *plat; > > struct stmmac_dma_cfg *dma_cfg; > > + bool legacy_mdio; > > int phy_mode; > > void *ret; > > int rc; > > @@ -471,10 +442,28 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) > > if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) > > dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); > > > > - /* To Configure PHY by using all device-tree supported properties */ > > - rc = stmmac_dt_phy(plat, np, &pdev->dev); > > - if (rc) > > - return ERR_PTR(rc); > > + plat->mdio_node = stmmac_of_get_mdio(np); > > + if (plat->mdio_node) > > + dev_dbg(&pdev->dev, "Found MDIO subnode\n"); > > + > > > + /* Legacy devicetrees allowed for no MDIO bus description and expect > > + * the bus to be scanned for devices. If there's no phy or fixed-link > > + * described assume this is the case since there must be something > > + * connected to the MAC. > > + */ > > + legacy_mdio = !of_phy_is_fixed_link(np) && !plat->phy_node; > > + if (legacy_mdio) > > + dev_info(&pdev->dev, "Deprecated MDIO bus assumption used\n"); > > + > > + if (plat->mdio_node || legacy_mdio) { > > + plat->mdio_bus_data = devm_kzalloc(&pdev->dev, > > + sizeof(struct stmmac_mdio_bus_data), > > + GFP_KERNEL); > > + if (!plat->mdio_bus_data) > > + return ERR_PTR(-ENOMEM); > > + > > + plat->mdio_bus_data->needs_reset = true; > > + } > > Why did you decide to move this out of the dedicated function? > stmmac_probe_config_dt() is already overwhelmed with various > non-coherent actions. The method has already got to being too long to > follow the kernel coding style limit (I have got a not submitted yet > cleanup patchset which step-by-step fixes that). Could you please get > the chunk above back to the respective function and, for instance, > just change it's name to something like stmmac_mdio_setup()? (I prefer > having "_setup" suffix because some of the locally defined static > methods already use it: stmmac_axi_setup(), stmmac_mtl_setup().) Sure, I can put it back in. I'll probably keep stmmac_of_get_mdio() (which is named in the style I see in the current file -- although as you highlight that shouldn't be taken as the best example of clean), and have stmmac_mdio_setup() call that and and mimic the inputs/outputs of the current function (moving the rest of the added code from stmmac_probe_config_dt() back into that function). Thanks for the feedback, let me know if you still think that abstraction isn't ideal (or wait till I post it :P) and I'll go with exactly as you said. I'm not _too_ opinionated on it, but thought stmmac_dt_phy() didn't explain much and stmmac_of_get_mdio() was self-explanatory enough that it helped readability. > > -Serge(y) > > > > > of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size); > > > > > > --- > > base-commit: fd8a79b63710acb84321be3ce74be23c876873fb > > change-id: 20231127-stmmac-no-mdio-node-1db9da8a25d9 > > > > Best regards, > > -- > > Andrew Halaney <ahalaney@redhat.com> > > > > >
On Thu, Dec 07, 2023 at 07:32:29AM -0600, Andrew Halaney wrote: > On Thu, Dec 07, 2023 at 02:56:25PM +0300, Serge Semin wrote: > > Hi Andrew > > > > On Wed, Dec 06, 2023 at 05:46:09PM -0600, Andrew Halaney wrote: > > > The stmmac_dt_phy() function, which parses the devicetree node of the > > > MAC and ultimately causes MDIO bus allocation, misinterprets what > > > fixed-link means in relation to the MAC's MDIO bus. This results in > > > a MDIO bus being created in situations it need not be. > > > > > > Currently a MDIO bus is created if the description is either: > > > > > > 1. Not fixed-link > > > 2. fixed-link but contains a MDIO bus as well > > > > > > The "1" case above isn't always accurate. If there's a phy-handle, > > > it could be referencing a phy on another MDIO controller's bus[1]. In > > > this case currently the MAC will make a MDIO bus and scan it all > > > anyways unnecessarily. > > > > > > There's also a lot of upstream devicetrees[2] that expect a MDIO bus to > > > be created and scanned for a phy. This case can also be inferred from > > > the platform description by not having a phy-handle && not being > > > fixed-link. This hits case "1" in the current driver's logic. > > > > > > Let's improve the logic to create a MDIO bus if either: > > > > > > - Devicetree contains a MDIO bus > > > - !fixed-link && !phy-handle (legacy handling) > > > > > > Below upstream devicetree snippets can be found that explain some of > > > the cases above more concretely. > > > > > > Here's[0] a devicetree example where the MAC is both fixed-link and > > > driving a switch on MDIO (case "2" above). This needs a MDIO bus to > > > be created: > > > > > > &fec1 { > > > phy-mode = "rmii"; > > > > > > fixed-link { > > > speed = <100>; > > > full-duplex; > > > }; > > > > > > mdio1: mdio { > > > switch0: switch0@0 { > > > compatible = "marvell,mv88e6190"; > > > pinctrl-0 = <&pinctrl_gpio_switch0>; > > > }; > > > }; > > > }; > > > > > > Here's[1] an example where there is no MDIO bus or fixed-link for > > > the ethernet1 MAC, so no MDIO bus should be created since ethernet0 > > > is the MDIO master for ethernet1's phy: > > > > > > ðernet0 { > > > phy-mode = "sgmii"; > > > phy-handle = <&sgmii_phy0>; > > > > > > mdio { > > > compatible = "snps,dwmac-mdio"; > > > sgmii_phy0: phy@8 { > > > compatible = "ethernet-phy-id0141.0dd4"; > > > reg = <0x8>; > > > device_type = "ethernet-phy"; > > > }; > > > > > > sgmii_phy1: phy@a { > > > compatible = "ethernet-phy-id0141.0dd4"; > > > reg = <0xa>; > > > device_type = "ethernet-phy"; > > > }; > > > }; > > > }; > > > > > > ðernet1 { > > > phy-mode = "sgmii"; > > > phy-handle = <&sgmii_phy1>; > > > }; > > > > > > Finally there's descriptions like this[2] which don't describe the > > > MDIO bus but expect it to be created and the whole address space > > > scanned for a phy since there's no phy-handle or fixed-link described: > > > > > > &gmac { > > > phy-supply = <&vcc_lan>; > > > phy-mode = "rmii"; > > > snps,reset-gpio = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>; > > > snps,reset-active-low; > > > snps,reset-delays-us = <0 10000 1000000>; > > > }; > > > > > > [0] https://elixir.bootlin.com/linux/v6.5-rc5/source/arch/arm/boot/dts/nxp/vf/vf610-zii-ssmb-dtu.dts > > > [1] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/qcom/sa8775p-ride.dts > > > [2] https://elixir.bootlin.com/linux/v6.6-rc5/source/arch/arm64/boot/dts/rockchip/rk3368-r88.dts#L164 > > > > Thank you for the patch. Please find a comment below. > > > > > > > > Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > > Signed-off-by: Andrew Halaney <ahalaney@redhat.com> > > > --- > > > .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 85 ++++++++++------------ > > > 1 file changed, 37 insertions(+), 48 deletions(-) > > > > > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > > > index 1ffde555da47..7da461fe93f6 100644 > > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > > > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > > > @@ -296,69 +296,39 @@ static int stmmac_mtl_setup(struct platform_device *pdev, > > > } > > > > > > /** > > > - * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources > > > - * @plat: driver data platform structure > > > - * @np: device tree node > > > - * @dev: device pointer > > > - * Description: > > > - * The mdio bus will be allocated in case of a phy transceiver is on board; > > > - * it will be NULL if the fixed-link is configured. > > > - * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated > > > - * in any case (for DSA, mdio must be registered even if fixed-link). > > > - * The table below sums the supported configurations: > > > - * ------------------------------- > > > - * snps,phy-addr | Y > > > - * ------------------------------- > > > - * phy-handle | Y > > > - * ------------------------------- > > > - * fixed-link | N > > > - * ------------------------------- > > > - * snps,dwmac-mdio | > > > - * even if | Y > > > - * fixed-link | > > > - * ------------------------------- > > > + * stmmac_of_get_mdio() - Gets the MDIO bus from the devicetree > > > + * @np: devicetree node > > > * > > > - * It returns 0 in case of success otherwise -ENODEV. > > > + * The MDIO bus will be searched for in the following ways: > > > + * 1. The compatible is "snps,dwc-qos-ethernet-4.10" && a "mdio" named > > > + * child node exists > > > + * 2. A child node with the "snps,dwmac-mdio" compatible is present > > > + * > > > + * Return: The MDIO node if present otherwise NULL > > > */ > > > -static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, > > > - struct device_node *np, struct device *dev) > > > +static struct device_node *stmmac_of_get_mdio(struct device_node *np) > > > { > > > - bool mdio = !of_phy_is_fixed_link(np); > > > static const struct of_device_id need_mdio_ids[] = { > > > { .compatible = "snps,dwc-qos-ethernet-4.10" }, > > > {}, > > > }; > > > + struct device_node *mdio_node = NULL; > > > > > > if (of_match_node(need_mdio_ids, np)) { > > > - plat->mdio_node = of_get_child_by_name(np, "mdio"); > > > + mdio_node = of_get_child_by_name(np, "mdio"); > > > } else { > > > /** > > > * If snps,dwmac-mdio is passed from DT, always register > > > * the MDIO > > > */ > > > - for_each_child_of_node(np, plat->mdio_node) { > > > - if (of_device_is_compatible(plat->mdio_node, > > > + for_each_child_of_node(np, mdio_node) { > > > + if (of_device_is_compatible(mdio_node, > > > "snps,dwmac-mdio")) > > > break; > > > } > > > } > > > > > > - if (plat->mdio_node) { > > > - dev_dbg(dev, "Found MDIO subnode\n"); > > > - mdio = true; > > > - } > > > - > > > - if (mdio) { > > > - plat->mdio_bus_data = > > > - devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data), > > > - GFP_KERNEL); > > > - if (!plat->mdio_bus_data) > > > - return -ENOMEM; > > > - > > > - plat->mdio_bus_data->needs_reset = true; > > > - } > > > - > > > - return 0; > > > + return mdio_node; > > > } > > > > > > /** > > > @@ -417,6 +387,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) > > > struct device_node *np = pdev->dev.of_node; > > > struct plat_stmmacenet_data *plat; > > > struct stmmac_dma_cfg *dma_cfg; > > > + bool legacy_mdio; > > > int phy_mode; > > > void *ret; > > > int rc; > > > @@ -471,10 +442,28 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) > > > if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) > > > dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); > > > > > > - /* To Configure PHY by using all device-tree supported properties */ > > > - rc = stmmac_dt_phy(plat, np, &pdev->dev); > > > - if (rc) > > > - return ERR_PTR(rc); > > > + plat->mdio_node = stmmac_of_get_mdio(np); > > > + if (plat->mdio_node) > > > + dev_dbg(&pdev->dev, "Found MDIO subnode\n"); > > > + > > > > > + /* Legacy devicetrees allowed for no MDIO bus description and expect > > > + * the bus to be scanned for devices. If there's no phy or fixed-link > > > + * described assume this is the case since there must be something > > > + * connected to the MAC. > > > + */ > > > + legacy_mdio = !of_phy_is_fixed_link(np) && !plat->phy_node; > > > + if (legacy_mdio) > > > + dev_info(&pdev->dev, "Deprecated MDIO bus assumption used\n"); > > > + > > > + if (plat->mdio_node || legacy_mdio) { > > > + plat->mdio_bus_data = devm_kzalloc(&pdev->dev, > > > + sizeof(struct stmmac_mdio_bus_data), > > > + GFP_KERNEL); > > > + if (!plat->mdio_bus_data) > > > + return ERR_PTR(-ENOMEM); > > > + > > > + plat->mdio_bus_data->needs_reset = true; > > > + } > > > > Why did you decide to move this out of the dedicated function? > > stmmac_probe_config_dt() is already overwhelmed with various > > non-coherent actions. The method has already got to being too long to > > follow the kernel coding style limit (I have got a not submitted yet > > cleanup patchset which step-by-step fixes that). Could you please get > > the chunk above back to the respective function and, for instance, > > just change it's name to something like stmmac_mdio_setup()? (I prefer > > having "_setup" suffix because some of the locally defined static > > methods already use it: stmmac_axi_setup(), stmmac_mtl_setup().) > > Sure, I can put it back in. I'll probably keep stmmac_of_get_mdio() > (which is named in the style I see in the current file -- although as > you highlight that shouldn't be taken as the best example of clean), > and have stmmac_mdio_setup() call that and and mimic the inputs/outputs > of the current function (moving the rest of the added code from > stmmac_probe_config_dt() back into that function). > > Thanks for the feedback, let me know if you still think that abstraction > isn't ideal (or wait till I post it :P) and I'll go with exactly as you > said. Sounds good. Thanks for taking my comment into account. > I'm not _too_ opinionated on it, but thought stmmac_dt_phy() > didn't explain much and stmmac_of_get_mdio() was self-explanatory enough > that it helped readability. You were right. stmmac_dt_phy() hasn't been explicitly doing PHY-related things since commit 74371272f97f ("net: stmmac: Convert to phylink and remove phylib logic"), but has been left with the MDIO stuff only. The function name wasn't that well chosen either. It didn't indicate what the function actually did, like "init", "get", "setup", etc. From that perspective your naming is much better - short and self-explanatory indeed. -Serge(y) > > > > > -Serge(y) > > > > > > > > of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size); > > > > > > > > > --- > > > base-commit: fd8a79b63710acb84321be3ce74be23c876873fb > > > change-id: 20231127-stmmac-no-mdio-node-1db9da8a25d9 > > > > > > Best regards, > > > -- > > > Andrew Halaney <ahalaney@redhat.com> > > > > > > > > >
On Wed, Dec 06, 2023 at 05:46:09PM -0600, Andrew Halaney wrote: > The stmmac_dt_phy() function, which parses the devicetree node of the > MAC and ultimately causes MDIO bus allocation, misinterprets what > fixed-link means in relation to the MAC's MDIO bus. This results in > a MDIO bus being created in situations it need not be. Please extend that with something like.... This is bad, because .... Most 'clean' driver unconditionally create the MDIO bus. But stmmac is not that clean, and has to keep backwards compatibility to some old usage. I'm just wondering what this patch actually brings us, and is it worth it. Is it fixing a real bug, or just an optimisation? Andrew
On Thu, Dec 07, 2023 at 10:30:23PM +0100, Andrew Lunn wrote: > On Wed, Dec 06, 2023 at 05:46:09PM -0600, Andrew Halaney wrote: > > The stmmac_dt_phy() function, which parses the devicetree node of the > > MAC and ultimately causes MDIO bus allocation, misinterprets what > > fixed-link means in relation to the MAC's MDIO bus. This results in > > a MDIO bus being created in situations it need not be. > > Please extend that with something like.... > > This is bad, because .... > > Most 'clean' driver unconditionally create the MDIO bus. But stmmac is > not that clean, and has to keep backwards compatibility to some old > usage. I'm just wondering what this patch actually brings us, and is > it worth it. Is it fixing a real bug, or just an optimisation? > > Andrew > It is an optimization for speeding up time to link up. I already sent out v3 moments before this arrived, I'll be sure to capture that more clearly in v4 (and wait a little longer before respinning it). I'm trying to optimize this device configuration (as shown in the commit): """ Here's[1] an example where there is no MDIO bus or fixed-link for the ethernet1 MAC, so no MDIO bus should be created since ethernet0 is the MDIO master for ethernet1's phy: ðernet0 { phy-mode = "sgmii"; phy-handle = <&sgmii_phy0>; mdio { compatible = "snps,dwmac-mdio"; sgmii_phy0: phy@8 { compatible = "ethernet-phy-id0141.0dd4"; reg = <0x8>; device_type = "ethernet-phy"; }; sgmii_phy1: phy@a { compatible = "ethernet-phy-id0141.0dd4"; reg = <0xa>; device_type = "ethernet-phy"; }; }; }; ðernet1 { phy-mode = "sgmii"; phy-handle = <&sgmii_phy1>; }; """ I'm seeing that ethernet1 scans the whole MDIO bus created for it, and finds nothing, wasting time in the process. Since there's no mdio bus described (since it's vacant) you get something like this call order: stmmac_mdio_register() of_mdiobus_register(new_bus, mdio_node) // mdio_node is NULL in this case __of_mdiobus_register(mdio, np, owner) // this doesn't set phy_mask since np == NULL __mdiobus_register(mdio, owner) mdiobus_scan_bus_c22(bus) mdiobus_scan_c22() // Called PHY_MAX_ADDR times, probing an empty bus Which is causing a good bit of delay in the time to link up, each attempted probe is taking about 5 ms and that's just benchmarking the get_phy_c22_id() calls, if you look at the whole loop it's greater (but I am unsure if that's just scheduling contention or something else going on, once I realized we were doing this work unnecessarily I decided to try and remove it) I know you said the standard is to make the MDIO bus unconditionally, but to me that feels like a waste, and describing say an empty MDIO bus (which would set the phy_mask for us eventually and not scan a bunch of phys, untested but I think that would work) seems like a bad description in the devicetree (I could definitely see describing an empty MDIO bus getting NACKed, but that's a guess). Please let me know if you disagree with that logic and have some alternative solutions for optimizing. In either case I think this code needs some cleaning so I'll carry this through. It also seems that unconditional creation of the MDIO bus is something that's biting some stmmac variants that lack an MDIO controller based on Serge's latest comments on v3: https://lore.kernel.org/netdev/jz6ot44fjkbmwcezi3fkgqd54nurglblbemrchfgxgq6udlhqz@ntepnnzzelta/ Thanks, Andrew
> I know you said the standard is to make the MDIO bus unconditionally, but > to me that feels like a waste, and describing say an empty MDIO bus > (which would set the phy_mask for us eventually and not scan a > bunch of phys, untested but I think that would work) seems like a bad > description in the devicetree (I could definitely see describing an > empty MDIO bus getting NACKed, but that's a guess). DT describes the hardware. The MDIO bus master exists. So typically the SoC .dtsi file would include it in the Ethernet node. At the SoC level it is empty, unless there is an integrated PHY in the SoC. The board .dts file then adds any PHYs to the node which the board actually has. So i doubt adding an empty MDIO node to the SoC .dtsi file will get NACKed, it correctly describes the hardware. Andrew
On Fri, Dec 08, 2023 at 02:14:41PM +0100, Andrew Lunn wrote: > > I know you said the standard is to make the MDIO bus unconditionally, but > > to me that feels like a waste, and describing say an empty MDIO bus > > (which would set the phy_mask for us eventually and not scan a > > bunch of phys, untested but I think that would work) seems like a bad > > description in the devicetree (I could definitely see describing an > > empty MDIO bus getting NACKed, but that's a guess). > > DT describes the hardware. The MDIO bus master exists. So typically > the SoC .dtsi file would include it in the Ethernet node. At the SoC > level it is empty, unless there is an integrated PHY in the SoC. The > board .dts file then adds any PHYs to the node which the board > actually has. > > So i doubt adding an empty MDIO node to the SoC .dtsi file will get > NACKed, it correctly describes the hardware. Agreed, thanks for helping me consider all the cases. In my particular example it would make sense to have SoC dtsi describe the mdio bus, leave it disabled, and boards enable it and describe components as necessary. So you have let's say these 8 abbreviated cases: Case 1 (MDIO bus used with phy on bus connected to MAC): ethernet { status = "okay"; phy-handle = <&phy0>; phy-mode = "rgmii"; mdio { status = "okay"; phy0: phy@0 { }; }; }; Case 2 (MDIO bus used but MAC's connect fixed-link): ethernet { status = "okay"; phy-mode = "rgmii"; fixed-link { }; mdio { status = "okay"; switch/unrelated-phy { }; }; }; Case 3 (MDIO bus used but MAC's connected to another bus's phy): ethernet { status = "okay"; phy-handle = <&phy1>; phy-mode = "rgmii"; mdio { status = "okay"; switch/unrelated-phy { }; }; }; Case 4 (MDIO bus disabled/unused, connected fixed-link): ethernet { status = "okay"; phy-mode = "rgmii"; fixed-link { }; mdio { status = "disabled"; }; }; Case 5 (MDIO bus disabled/unused, connected to another bus's phy): ethernet { status = "okay"; phy-handle = <&phy1>; phy-mode = "rgmii"; mdio { status = "disabled"; }; }; Case 6 (MDIO bus not described, connected fixed-link): ethernet { status = "okay"; phy-mode = "rgmii"; fixed-link { }; }; Case 7 (MDIO bus not described, connected to a different bus's phy): ethernet { status = "okay"; phy-handle = <&phy1>; phy-mode = "rgmii"; }; Case 8 (MDIO bus not described, but phy on MDIO bus is connected to MAC, legacy description[2] in my commit message): ethernet { status = "okay"; }; If we look at the logic in stmmac today about how to handle the MDIO bus, you've got basically: if !fixed-link || mdio_node_present() of_mdiobus_register(np) Applying current stmmac logic to our cases... Case 1 (MDIO bus used with phy on bus connected to MAC): MDIO bus made, no unnecessary scanning Case 2 (MDIO bus used but MAC's fixed-link): MDIO bus made, no unnecessary scanning Case 3 (MDIO bus used but MAC's connected to another bus's phy): MDIO bus made, no unnecessary scanning Case 4 (MDIO bus disabled/unused, connected fixed-link): MDIO bus attempted to be made, fails -ENODEV due to disabled and stmmac returns -ENODEV from probe too Case 5 (MDIO bus disabled/unused, connected to another bus's phy): MDIO bus attempted to be made, fails -ENODEV due to disabled and stmmac returns -ENODEV from probe too Case 6 (MDIO bus not described, connected fixed-link): MDIO bus not created Case 7 (MDIO bus not described, connected to a different bus's phy): MDIO bus created, but the whole bus is scanned Case 8 (MDIO bus not described, but phy on MDIO bus is connected to MAC, legacy description[2] in my commit message): MDIO bus created, the whole bus is scanned and the undescribed but necessary phy is found The things I note of interest are cases 4, 5, 7, 8. Cases 4/5 are a bug in stmmac IMO, which breaks the devicetree description you mentioned as ideal in my case. Case 7 is the one I'm currently working with, and the devicetree can be updated to match case 5, but right now case 7 makes a bus and scans it needlessly which isn't great. It _sounds_ like to me Serge knows of stmmac variants that also *do not* have an MDIO controller, so they'd fall in this case too and really shouldn't create a bus. Case 8 is the legacy one that I wish didn't exist, but it does, and for that reason we should continue to make a bus and scan the whole thing if we can't figure out what the MAC's connected to. So in my opinion there's 3 changes I want to make based on all the use cases I could think of: 1. This patch, which improves the stmmac logic and stops making a bus for case 7 2. A new patch to gracefully handle cases 4/5, where currently if the MDIO bus is disabled in the devicetree, as it should be, stmmac handles -ENODEV from of_mdiobus_register() as a failure instead of gracefully continuing knowing this is fine and dandy. 3. Clean up the sa8775p dts to have the MDIO bus described in the SoC dtsi and left disabled instead of undescribed (a more accurate hardware description). Please let me know if you see any holes in my logic, hopefully the wall of text is useful in explaining how I got here. Thanks, Andrew
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 1ffde555da47..7da461fe93f6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -296,69 +296,39 @@ static int stmmac_mtl_setup(struct platform_device *pdev, } /** - * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources - * @plat: driver data platform structure - * @np: device tree node - * @dev: device pointer - * Description: - * The mdio bus will be allocated in case of a phy transceiver is on board; - * it will be NULL if the fixed-link is configured. - * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated - * in any case (for DSA, mdio must be registered even if fixed-link). - * The table below sums the supported configurations: - * ------------------------------- - * snps,phy-addr | Y - * ------------------------------- - * phy-handle | Y - * ------------------------------- - * fixed-link | N - * ------------------------------- - * snps,dwmac-mdio | - * even if | Y - * fixed-link | - * ------------------------------- + * stmmac_of_get_mdio() - Gets the MDIO bus from the devicetree + * @np: devicetree node * - * It returns 0 in case of success otherwise -ENODEV. + * The MDIO bus will be searched for in the following ways: + * 1. The compatible is "snps,dwc-qos-ethernet-4.10" && a "mdio" named + * child node exists + * 2. A child node with the "snps,dwmac-mdio" compatible is present + * + * Return: The MDIO node if present otherwise NULL */ -static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, - struct device_node *np, struct device *dev) +static struct device_node *stmmac_of_get_mdio(struct device_node *np) { - bool mdio = !of_phy_is_fixed_link(np); static const struct of_device_id need_mdio_ids[] = { { .compatible = "snps,dwc-qos-ethernet-4.10" }, {}, }; + struct device_node *mdio_node = NULL; if (of_match_node(need_mdio_ids, np)) { - plat->mdio_node = of_get_child_by_name(np, "mdio"); + mdio_node = of_get_child_by_name(np, "mdio"); } else { /** * If snps,dwmac-mdio is passed from DT, always register * the MDIO */ - for_each_child_of_node(np, plat->mdio_node) { - if (of_device_is_compatible(plat->mdio_node, + for_each_child_of_node(np, mdio_node) { + if (of_device_is_compatible(mdio_node, "snps,dwmac-mdio")) break; } } - if (plat->mdio_node) { - dev_dbg(dev, "Found MDIO subnode\n"); - mdio = true; - } - - if (mdio) { - plat->mdio_bus_data = - devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data), - GFP_KERNEL); - if (!plat->mdio_bus_data) - return -ENOMEM; - - plat->mdio_bus_data->needs_reset = true; - } - - return 0; + return mdio_node; } /** @@ -417,6 +387,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) struct device_node *np = pdev->dev.of_node; struct plat_stmmacenet_data *plat; struct stmmac_dma_cfg *dma_cfg; + bool legacy_mdio; int phy_mode; void *ret; int rc; @@ -471,10 +442,28 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); - /* To Configure PHY by using all device-tree supported properties */ - rc = stmmac_dt_phy(plat, np, &pdev->dev); - if (rc) - return ERR_PTR(rc); + plat->mdio_node = stmmac_of_get_mdio(np); + if (plat->mdio_node) + dev_dbg(&pdev->dev, "Found MDIO subnode\n"); + + /* Legacy devicetrees allowed for no MDIO bus description and expect + * the bus to be scanned for devices. If there's no phy or fixed-link + * described assume this is the case since there must be something + * connected to the MAC. + */ + legacy_mdio = !of_phy_is_fixed_link(np) && !plat->phy_node; + if (legacy_mdio) + dev_info(&pdev->dev, "Deprecated MDIO bus assumption used\n"); + + if (plat->mdio_node || legacy_mdio) { + plat->mdio_bus_data = devm_kzalloc(&pdev->dev, + sizeof(struct stmmac_mdio_bus_data), + GFP_KERNEL); + if (!plat->mdio_bus_data) + return ERR_PTR(-ENOMEM); + + plat->mdio_bus_data->needs_reset = true; + } of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);