From: Calvin Johnson <hidden> Date: 2021-02-08 16:39:27
This patch set provides ACPI support to DPAA2 network drivers.
It also introduces new fwnode based APIs to support phylink and phy
layers
Following functions are defined:
phylink_fwnode_phy_connect()
fwnode_mdiobus_register_phy()
fwnode_mdiobus_register()
fwnode_get_phy_id()
fwnode_phy_find_device()
device_phy_find_device()
fwnode_get_phy_node()
fwnode_mdio_find_device()
acpi_get_local_address()
First one helps in connecting phy to phylink instance.
Next three helps in getting phy_id and registering phy to mdiobus
Next two help in finding a phy on a mdiobus.
Next one helps in getting phy_node from a fwnode.
Last one is used to get local address from _ADR object.
Corresponding OF functions are refactored.
Tested-on: T2080RDB, LS1046ARDB, LS2088ARDB and LX2160ARDB
Changes in v5:
- More cleanup
- Replace fwnode_get_id() with acpi_get_local_address()
- add missing MODULE_LICENSE()
- replace fwnode_get_id() with OF and ACPI function calls
- replace fwnode_get_id() with OF and ACPI function calls
Changes in v4:
- More cleanup
- Improve code structure to handle all cases
- Remove redundant else from fwnode_mdiobus_register()
- Cleanup xgmac_mdio_probe()
- call phy_device_free() before returning
Changes in v3:
- Add more info on legacy DT properties "phy" and "phy-device"
- Redefine fwnode_phy_find_device() to follow of_phy_find_device()
- Use traditional comparison pattern
- Use GENMASK
- Modified to retrieve reg property value for ACPI as well
- Resolved compilation issue with CONFIG_ACPI = n
- Added more info into documentation
- Use acpi_mdiobus_register()
- Avoid unnecessary line removal
- Remove unused inclusion of acpi.h
Changes in v2:
- Updated with more description in document
- use reverse christmas tree ordering for local variables
- Refactor OF functions to use fwnode functions
Calvin Johnson (15):
Documentation: ACPI: DSD: Document MDIO PHY
net: phy: Introduce fwnode_mdio_find_device()
net: phy: Introduce phy related fwnode functions
of: mdio: Refactor of_phy_find_device()
net: phy: Introduce fwnode_get_phy_id()
of: mdio: Refactor of_get_phy_id()
net: mdiobus: Introduce fwnode_mdiobus_register_phy()
of: mdio: Refactor of_mdiobus_register_phy()
ACPI: utils: Introduce acpi_get_local_address()
net: mdio: Add ACPI support code for mdio
net: mdiobus: Introduce fwnode_mdiobus_register()
net/fsl: Use fwnode_mdiobus_register()
phylink: introduce phylink_fwnode_phy_connect()
net: phylink: Refactor phylink_of_phy_connect()
net: dpaa2-mac: Add ACPI support for DPAA2 MAC driver
Documentation/firmware-guide/acpi/dsd/phy.rst | 133 ++++++++++++++++++
MAINTAINERS | 1 +
drivers/acpi/utils.c | 14 ++
.../net/ethernet/freescale/dpaa2/dpaa2-mac.c | 91 +++++++-----
drivers/net/ethernet/freescale/xgmac_mdio.c | 11 +-
drivers/net/mdio/Kconfig | 7 +
drivers/net/mdio/Makefile | 1 +
drivers/net/mdio/acpi_mdio.c | 51 +++++++
drivers/net/mdio/of_mdio.c | 79 +----------
drivers/net/phy/mdio_bus.c | 86 +++++++++++
drivers/net/phy/phy_device.c | 106 ++++++++++++++
drivers/net/phy/phylink.c | 53 ++++---
include/linux/acpi.h | 7 +
include/linux/acpi_mdio.h | 27 ++++
include/linux/mdio.h | 2 +
include/linux/of_mdio.h | 6 +-
include/linux/phy.h | 32 +++++
include/linux/phylink.h | 3 +
18 files changed, 578 insertions(+), 132 deletions(-)
create mode 100644 Documentation/firmware-guide/acpi/dsd/phy.rst
create mode 100644 drivers/net/mdio/acpi_mdio.c
create mode 100644 include/linux/acpi_mdio.h
--
2.17.1
From: Calvin Johnson <hidden> Date: 2021-02-08 16:39:29
Extract phy_id from compatible string. This will be used by
fwnode_mdiobus_register_phy() to create phy device using the
phy_id.
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5: None
Changes in v4: None
Changes in v3:
- Use traditional comparison pattern
- Use GENMASK
Changes in v2: None
drivers/net/phy/phy_device.c | 21 +++++++++++++++++++++
include/linux/phy.h | 5 +++++
2 files changed, 26 insertions(+)
@@ -846,6 +846,27 @@ static int get_phy_c22_id(struct mii_bus *bus, int addr, u32 *phy_id)return0;}+/* Extract the phy ID from the compatible string of the form+*ethernet-phy-idAAAA.BBBB.+*/+intfwnode_get_phy_id(structfwnode_handle*fwnode,u32*phy_id)+{+unsignedintupper,lower;+constchar*cp;+intret;++ret=fwnode_property_read_string(fwnode,"compatible",&cp);+if(ret)+returnret;++if(sscanf(cp,"ethernet-phy-id%4x.%4x",&upper,&lower)!=2)+return-EINVAL;++*phy_id=((upper&GENMASK(15,0))<<16)|(lower&GENMASK(15,0));+return0;+}+EXPORT_SYMBOL(fwnode_get_phy_id);+/***get_phy_device-readsthespecifiedPHYdeviceandreturnsits@phy_device*struct
From: Calvin Johnson <hidden> Date: 2021-02-08 16:39:53
Introduce ACPI mechanism to get PHYs registered on a MDIO bus and
provide them to be connected to MAC.
Describe properties "phy-handle" and "phy-mode".
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5:
- More cleanup
Changes in v4:
- More cleanup
Changes in v3: None
Changes in v2:
- Updated with more description in document
Documentation/firmware-guide/acpi/dsd/phy.rst | 133 ++++++++++++++++++
1 file changed, 133 insertions(+)
create mode 100644 Documentation/firmware-guide/acpi/dsd/phy.rst
@@ -0,0 +1,133 @@+.. SPDX-License-Identifier: GPL-2.0++=========================+MDIO bus and PHYs in ACPI+=========================++The PHYs on an MDIO bus [1] are probed and registered using+fwnode_mdiobus_register_phy().++Later, for connecting these PHYs to MAC, the PHYs registered on the+MDIO bus have to be referenced.++This document introduces two _DSD properties that are to be used+for connecting PHYs on the MDIO bus [3] to the MAC layer.++These properties are defined in accordance with the "Device+Properties UUID For _DSD" [2] document and the+daffd814-6eba-4d8c-8a91-bc9bbf4aa301 UUID must be used in the Device+Data Descriptors containing them.++phy-handle+----------+For each MAC node, a device property "phy-handle" is used to reference+the PHY that is registered on an MDIO bus. This is mandatory for+network interfaces that have PHYs connected to MAC via MDIO bus.++During the MDIO bus driver initialization, PHYs on this bus are probed+using the _ADR object as shown below and are registered on the MDIO bus.++::+ Scope(\_SB.MDI0)+ {+ Device(PHY1) {+ Name (_ADR, 0x1)+ } // end of PHY1++ Device(PHY2) {+ Name (_ADR, 0x2)+ } // end of PHY2+ }++Later, during the MAC driver initialization, the registered PHY devices+have to be retrieved from the MDIO bus. For this, the MAC driver need+references to the previously registered PHYs which are provided+as device object references (e.g. \_SB.MDI0.PHY1).++phy-mode+--------+The "phy-mode" _DSD property is used to describe the connection to+the PHY. The valid values for "phy-mode" are defined in [4].++The following ASL example illustrates the usage of these properties.++DSDT entry for MDIO node+------------------------++The MDIO bus has an SoC component (MDIO controller) and a platform+component (PHYs on the MDIO bus).++a) Silicon Component+This node describes the MDIO controller, MDI0+---------------------------------------------+::+ Scope(_SB)+ {+ Device(MDI0) {+ Name(_HID, "NXP0006")+ Name(_CCA, 1)+ Name(_UID, 0)+ Name(_CRS, ResourceTemplate() {+ Memory32Fixed(ReadWrite, MDI0_BASE, MDI_LEN)+ Interrupt(ResourceConsumer, Level, ActiveHigh, Shared)+ {+ MDI0_IT+ }+ }) // end of _CRS for MDI0+ } // end of MDI0+ }++b) Platform Component+The PHY1 and PHY2 nodes represent the PHYs connected to MDIO bus MDI0+---------------------------------------------------------------------+::+ Scope(\_SB.MDI0)+ {+ Device(PHY1) {+ Name (_ADR, 0x1)+ } // end of PHY1++ Device(PHY2) {+ Name (_ADR, 0x2)+ } // end of PHY2+ }++DSDT entries representing MAC nodes+-----------------------------------++Below are the MAC nodes where PHY nodes are referenced.+phy-mode and phy-handle are used as explained earlier.+------------------------------------------------------+::+ Scope(\_SB.MCE0.PR17)+ {+ Name (_DSD, Package () {+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),+ Package () {+ Package (2) {"phy-mode", "rgmii-id"},+ Package (2) {"phy-handle", \_SB.MDI0.PHY1}+ }+ })+ }++ Scope(\_SB.MCE0.PR18)+ {+ Name (_DSD, Package () {+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),+ Package () {+ Package (2) {"phy-mode", "rgmii-id"},+ Package (2) {"phy-handle", \_SB.MDI0.PHY2}}+ }+ })+ }++References+==========++[1] Documentation/networking/phy.rst++[2] https://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf++[3] Documentation/firmware-guide/acpi/DSD-properties-rules.rst++[4] Documentation/devicetree/bindings/net/ethernet-controller.yaml
From: Calvin Johnson <hidden> Date: 2021-02-08 16:42:16
With the introduction of fwnode_get_phy_id(), refactor of_get_phy_id()
to use fwnode equivalent.
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/net/mdio/of_mdio.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
From: Calvin Johnson <hidden> Date: 2021-02-08 16:43:02
Define fwnode_mdio_find_device() to get a pointer to the
mdio_device from fwnode passed to the function.
Refactor of_mdio_find_device() to use fwnode_mdio_find_device().
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/net/mdio/of_mdio.c | 11 +----------
drivers/net/phy/phy_device.c | 23 +++++++++++++++++++++++
include/linux/phy.h | 6 ++++++
3 files changed, 30 insertions(+), 10 deletions(-)
From: Calvin Johnson <hidden> Date: 2021-02-08 16:47:08
Define phylink_fwnode_phy_connect() to connect phy specified by
a fwnode to a phylink instance.
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5: None
Changes in v4:
- call phy_device_free() before returning
Changes in v3: None
Changes in v2: None
drivers/net/phy/phylink.c | 56 +++++++++++++++++++++++++++++++++++++++
include/linux/phylink.h | 3 +++
2 files changed, 59 insertions(+)
@@ -1120,6 +1121,61 @@ int phylink_of_phy_connect(struct phylink *pl, struct device_node *dn,}EXPORT_SYMBOL_GPL(phylink_of_phy_connect);+/**+*phylink_fwnode_phy_connect()-connectthePHYspecifiedinthefwnode.+*@pl:apointertoa&structphylinkreturnedfromphylink_create()+*@fwnode:apointertoa&structfwnode_handle.+*@flags:PHY-specificflagstocommunicatetothePHYdevicedriver+*+*Connectthephyspecified@fwnodetothephylinkinstancespecified+*by@pl.+*+*Returns0onsuccessoranegativeerrno.+*/+intphylink_fwnode_phy_connect(structphylink*pl,+structfwnode_handle*fwnode,+u32flags)+{+structfwnode_handle*phy_fwnode;+structphy_device*phy_dev;+intret;++if(is_of_node(fwnode)){+/* Fixed links and 802.3z are handled without needing a PHY */+if(pl->cfg_link_an_mode==MLO_AN_FIXED||+(pl->cfg_link_an_mode==MLO_AN_INBAND&&+phy_interface_mode_is_8023z(pl->link_interface)))+return0;+}++phy_fwnode=fwnode_get_phy_node(fwnode);+if(IS_ERR(phy_fwnode)){+if(pl->cfg_link_an_mode==MLO_AN_PHY)+return-ENODEV;+return0;+}++phy_dev=fwnode_phy_find_device(phy_fwnode);+/* We're done with the phy_node handle */+fwnode_handle_put(phy_fwnode);+if(!phy_dev)+return-ENODEV;++ret=phy_attach_direct(pl->netdev,phy_dev,flags,+pl->link_interface);+if(ret){+phy_device_free(phy_dev);+returnret;+}++ret=phylink_bringup_phy(pl,phy_dev,pl->link_config.interface);+if(ret)+phy_detach(phy_dev);++returnret;+}+EXPORT_SYMBOL_GPL(phylink_fwnode_phy_connect);+/***phylink_disconnect_phy()-disconnectanyPHYattachedtothephylink*instance.
From: Calvin Johnson <hidden> Date: 2021-02-08 16:48:20
Define fwnode_phy_find_device() to iterate an mdiobus and find the
phy device of the provided phy fwnode. Additionally define
device_phy_find_device() to find phy device of provided device.
Define fwnode_get_phy_node() to get phy_node using named reference.
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5: None
Changes in v4: None
Changes in v3:
- Add more info on legacy DT properties "phy" and "phy-device"
- Redefine fwnode_phy_find_device() to follow of_phy_find_device()
Changes in v2:
- use reverse christmas tree ordering for local variables
drivers/net/phy/phy_device.c | 62 ++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 20 ++++++++++++
2 files changed, 82 insertions(+)
@@ -2852,6 +2853,67 @@ struct mdio_device *fwnode_mdio_find_device(struct fwnode_handle *fwnode)}EXPORT_SYMBOL(fwnode_mdio_find_device);+/**+*fwnode_phy_find_device-Forprovidedphy_fwnode,findphy_device.+*+*@phy_fwnode:Pointertothephy'sfwnode.+*+*Ifsuccessful,returnsapointertothephy_devicewiththeembedded+*structdevicerefcountincrementedbyone,orNULLonfailure.+*/+structphy_device*fwnode_phy_find_device(structfwnode_handle*phy_fwnode)+{+structmdio_device*mdiodev;++mdiodev=fwnode_mdio_find_device(phy_fwnode);+if(!mdiodev)+returnNULL;++if(mdiodev->flags&MDIO_DEVICE_FLAG_PHY)+returnto_phy_device(&mdiodev->dev);++put_device(&mdiodev->dev);++returnNULL;+}+EXPORT_SYMBOL(fwnode_phy_find_device);++/**+*device_phy_find_device-Forthegivendevice,getthephy_device+*@dev:Pointertothegivendevice+*+*Referreturnconditionsoffwnode_phy_find_device().+*/+structphy_device*device_phy_find_device(structdevice*dev)+{+returnfwnode_phy_find_device(dev_fwnode(dev));+}+EXPORT_SYMBOL_GPL(device_phy_find_device);++/**+*fwnode_get_phy_node-Getthephy_nodeusingthenamedreference.+*@fwnode:Pointertofwnodefromwhichphy_nodehastobeobtained.+*+*Referreturnconditionsoffwnode_find_reference().+*ForACPI,only"phy-handle"issupported.LegacyDTproperties"phy"+*and"phy-device"arenotsupportedinACPI.DTsupportsallthethree+*namedreferencestothephynode.+*/+structfwnode_handle*fwnode_get_phy_node(structfwnode_handle*fwnode)+{+structfwnode_handle*phy_node;++/* Only phy-handle is used for ACPI */+phy_node=fwnode_find_reference(fwnode,"phy-handle",0);+if(is_acpi_node(fwnode)||!IS_ERR(phy_node))+returnphy_node;+phy_node=fwnode_find_reference(fwnode,"phy",0);+if(IS_ERR(phy_node))+phy_node=fwnode_find_reference(fwnode,"phy-device",0);+returnphy_node;+}+EXPORT_SYMBOL_GPL(fwnode_get_phy_node);+/***phy_probe-probeandinitaPHYdevice*@dev:devicetoprobeandinit
From: Calvin Johnson <hidden> Date: 2021-02-08 16:49:56
Introduce fwnode_mdiobus_register_phy() to register PHYs on the
mdiobus. From the compatible string, identify whether the PHY is
c45 and based on this create a PHY device instance which is
registered on the mdiobus.
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/net/mdio/of_mdio.c | 3 +-
drivers/net/phy/mdio_bus.c | 65 ++++++++++++++++++++++++++++++++++++++
include/linux/mdio.h | 2 ++
include/linux/of_mdio.h | 6 +++-
4 files changed, 74 insertions(+), 2 deletions(-)
@@ -106,6 +107,70 @@ int mdiobus_unregister_device(struct mdio_device *mdiodev)}EXPORT_SYMBOL(mdiobus_unregister_device);+intfwnode_mdiobus_register_phy(structmii_bus*bus,+structfwnode_handle*child,u32addr)+{+structmii_timestamper*mii_ts;+structphy_device*phy;+boolis_c45=false;+u32phy_id;+intrc;++if(is_of_node(child)){+mii_ts=of_find_mii_timestamper(to_of_node(child));+if(IS_ERR(mii_ts))+returnPTR_ERR(mii_ts);+}++rc=fwnode_property_match_string(child,"compatible","ethernet-phy-ieee802.3-c45");+if(rc>=0)+is_c45=true;++if(is_c45||fwnode_get_phy_id(child,&phy_id))+phy=get_phy_device(bus,addr,is_c45);+else+phy=phy_device_create(bus,addr,phy_id,0,NULL);+if(IS_ERR(phy)){+if(mii_ts&&is_of_node(child))+unregister_mii_timestamper(mii_ts);+returnPTR_ERR(phy);+}++if(is_acpi_node(child)){+phy->irq=bus->irq[addr];++/* Associate the fwnode with the device structure so it+*canbelookeduplater.+*/+phy->mdio.dev.fwnode=child;++/* All data is now stored in the phy struct, so register it */+rc=phy_device_register(phy);+if(rc){+phy_device_free(phy);+fwnode_handle_put(phy->mdio.dev.fwnode);+returnrc;+}+}elseif(is_of_node(child)){+rc=of_mdiobus_phy_device_register(bus,phy,to_of_node(child),addr);+if(rc){+if(mii_ts)+unregister_mii_timestamper(mii_ts);+phy_device_free(phy);+returnrc;+}++/* phy->mii_ts may already be defined by the PHY driver. A+*mii_timestamperprobedviathedevicetreewillstillhave+*precedence.+*/+if(mii_ts)+phy->mii_ts=mii_ts;+}+return0;+}+EXPORT_SYMBOL(fwnode_mdiobus_register_phy);+structphy_device*mdiobus_get_phy(structmii_bus*bus,intaddr){structmdio_device*mdiodev=bus->mdio_map[addr];
From: Calvin Johnson <hidden> Date: 2021-02-08 16:50:31
Introduce a wrapper around the _ADR evaluation.
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5:
- Replace fwnode_get_id() with acpi_get_local_address()
Changes in v4:
- Improve code structure to handle all cases
Changes in v3:
- Modified to retrieve reg property value for ACPI as well
- Resolved compilation issue with CONFIG_ACPI = n
- Added more info into documentation
Changes in v2: None
drivers/acpi/utils.c | 14 ++++++++++++++
include/linux/acpi.h | 7 +++++++
2 files changed, 21 insertions(+)
@@ -98,45 +98,7 @@ EXPORT_SYMBOL(of_mdiobus_phy_device_register);staticintof_mdiobus_register_phy(structmii_bus*mdio,structdevice_node*child,u32addr){-structmii_timestamper*mii_ts;-structphy_device*phy;-boolis_c45;-intrc;-u32phy_id;--mii_ts=of_find_mii_timestamper(child);-if(IS_ERR(mii_ts))-returnPTR_ERR(mii_ts);--is_c45=of_device_is_compatible(child,-"ethernet-phy-ieee802.3-c45");--if(!is_c45&&!of_get_phy_id(child,&phy_id))-phy=phy_device_create(mdio,addr,phy_id,0,NULL);-else-phy=get_phy_device(mdio,addr,is_c45);-if(IS_ERR(phy)){-if(mii_ts)-unregister_mii_timestamper(mii_ts);-returnPTR_ERR(phy);-}--rc=of_mdiobus_phy_device_register(mdio,phy,child,addr);-if(rc){-if(mii_ts)-unregister_mii_timestamper(mii_ts);-phy_device_free(phy);-returnrc;-}--/* phy->mii_ts may already be defined by the PHY driver. A-*mii_timestamperprobedviathedevicetreewillstillhave-*precedence.-*/-if(mii_ts)-phy->mii_ts=mii_ts;--return0;+returnfwnode_mdiobus_register_phy(mdio,of_fwnode_handle(child),addr);}staticintof_mdiobus_register_device(structmii_bus*mdio,
From: Calvin Johnson <hidden> Date: 2021-02-08 16:53:19
fwnode_mdiobus_register() internally takes care of both DT
and ACPI cases to register mdiobus. Replace existing
of_mdiobus_register() with fwnode_mdiobus_register().
Note: For both ACPI and DT cases, endianness of MDIO controller
need to be specified using "little-endian" property.
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5: None
Changes in v4:
- Cleanup xgmac_mdio_probe()
Changes in v3:
- Avoid unnecessary line removal
- Remove unused inclusion of acpi.h
Changes in v2: None
drivers/net/ethernet/freescale/xgmac_mdio.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
@@ -243,10 +244,9 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)staticintxgmac_mdio_probe(structplatform_device*pdev){-structdevice_node*np=pdev->dev.of_node;-structmii_bus*bus;-structresource*res;structmdio_fsl_priv*priv;+structresource*res;+structmii_bus*bus;intret;/* In DPAA-1, MDIO is one of the many FMan sub-devices. The FMan
@@ -279,13 +279,16 @@ static int xgmac_mdio_probe(struct platform_device *pdev)gotoerr_ioremap;}+/* For both ACPI and DT cases, endianness of MDIO controller+*needstobespecifiedusing"little-endian"property.+*/priv->is_little_endian=device_property_read_bool(&pdev->dev,"little-endian");priv->has_a011043=device_property_read_bool(&pdev->dev,"fsl,erratum-a011043");-ret=of_mdiobus_register(bus,np);+ret=fwnode_mdiobus_register(bus,pdev->dev.fwnode);if(ret){dev_err(&pdev->dev,"cannot register MDIO bus\n");gotoerr_registration;
@@ -2,6 +2,7 @@# Makefile for Linux MDIO bus driversobj-$(CONFIG_OF_MDIO)+=of_mdio.o+obj-$(CONFIG_ACPI_MDIO)+=acpi_mdio.oobj-$(CONFIG_MDIO_ASPEED)+=mdio-aspeed.oobj-$(CONFIG_MDIO_BCM_IPROC)+=mdio-bcm-iproc.o
@@ -0,0 +1,51 @@+// SPDX-License-Identifier: GPL-2.0-only+/*+*ACPIhelpersfortheMDIO(EthernetPHY)API+*+*ThisfileprovideshelperfunctionsforextractingPHYdeviceinformation+*outoftheACPIASLandusingittopopulateanmii_bus.+*/++#include<linux/acpi.h>+#include<linux/acpi_mdio.h>++MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>");+MODULE_LICENSE("GPL");++/**+*acpi_mdiobus_register-Registermii_busandcreatePHYsfromtheACPIASL.+*+*@mdio:pointertomii_busstructure+*@fwnode:pointertofwnodeofMDIObus.+*+*Thisfunctionregistersthemii_busstructureandregistersaphy_device+*foreachchildnodeof@fwnode.+*/+intacpi_mdiobus_register(structmii_bus*mdio,structfwnode_handle*fwnode)+{+structfwnode_handle*child;+u32addr;+intret;++/* Mask out all PHYs from auto probing. */+mdio->phy_mask=~0;+ret=mdiobus_register(mdio);+if(ret)+returnret;++mdio->dev.fwnode=fwnode;+/* Loop over the child nodes and register a phy_device for each PHY */+fwnode_for_each_child_node(fwnode,child){+ret=acpi_get_local_address(ACPI_HANDLE_FWNODE(child),&addr);+if((ret)||addr>=PHY_MAX_ADDR)+continue;++ret=fwnode_mdiobus_register_phy(mdio,child,addr);+if(ret==-ENODEV)+dev_err(&mdio->dev,+"MDIO device at address %d is missing.\n",+addr);+}+return0;+}+EXPORT_SYMBOL(acpi_mdiobus_register);
@@ -1080,44 +1080,7 @@ EXPORT_SYMBOL_GPL(phylink_connect_phy);intphylink_of_phy_connect(structphylink*pl,structdevice_node*dn,u32flags){-structdevice_node*phy_node;-structphy_device*phy_dev;-intret;--/* Fixed links and 802.3z are handled without needing a PHY */-if(pl->cfg_link_an_mode==MLO_AN_FIXED||-(pl->cfg_link_an_mode==MLO_AN_INBAND&&-phy_interface_mode_is_8023z(pl->link_interface)))-return0;--phy_node=of_parse_phandle(dn,"phy-handle",0);-if(!phy_node)-phy_node=of_parse_phandle(dn,"phy",0);-if(!phy_node)-phy_node=of_parse_phandle(dn,"phy-device",0);--if(!phy_node){-if(pl->cfg_link_an_mode==MLO_AN_PHY)-return-ENODEV;-return0;-}--phy_dev=of_phy_find_device(phy_node);-/* We're done with the phy_node handle */-of_node_put(phy_node);-if(!phy_dev)-return-ENODEV;--ret=phy_attach_direct(pl->netdev,phy_dev,flags,-pl->link_interface);-if(ret)-returnret;--ret=phylink_bringup_phy(pl,phy_dev,pl->link_config.interface);-if(ret)-phy_detach(phy_dev);--returnret;+returnphylink_fwnode_phy_connect(pl,of_fwnode_handle(dn),flags);}EXPORT_SYMBOL_GPL(phylink_of_phy_connect);
From: Calvin Johnson <hidden> Date: 2021-02-08 17:39:12
Modify dpaa2_mac_connect() to support ACPI along with DT.
Modify dpaa2_mac_get_node() to get the dpmac fwnode from either
DT or ACPI.
Replace of_get_phy_mode with fwnode_get_phy_mode to get
phy-mode for a dpmac_node.
Use helper function phylink_fwnode_phy_connect() to find phy_dev and
connect to mac->phylink.
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5:
- replace fwnode_get_id() with OF and ACPI function calls
Changes in v4: None
Changes in v3: None
Changes in v2:
- Refactor OF functions to use fwnode functions
.../net/ethernet/freescale/dpaa2/dpaa2-mac.c | 91 +++++++++++--------
1 file changed, 54 insertions(+), 37 deletions(-)
@@ -34,39 +37,51 @@ static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode)return0;}-/* Caller must call of_node_put on the returned value */-staticstructdevice_node*dpaa2_mac_get_node(u16dpmac_id)+staticstructfwnode_handle*dpaa2_mac_get_node(structdevice*dev,+u16dpmac_id){-structdevice_node*dpmacs,*dpmac=NULL;-u32id;+structfwnode_handle*parent,*child=NULL;+structdevice_node*dpmacs=NULL;interr;+u32id;-dpmacs=of_find_node_by_name(NULL,"dpmacs");-if(!dpmacs)-returnNULL;+if(is_of_node(dev->parent->fwnode)){+dpmacs=of_find_node_by_name(NULL,"dpmacs");+if(!dpmacs)+returnNULL;+parent=of_fwnode_handle(dpmacs);+}elseif(is_acpi_node(dev->parent->fwnode)){+parent=dev->parent->fwnode;+}-while((dpmac=of_get_next_child(dpmacs,dpmac))!=NULL){-err=of_property_read_u32(dpmac,"reg",&id);-if(err)+fwnode_for_each_child_node(parent,child){+err=-EINVAL;+if(is_acpi_device_node(child))+err=acpi_get_local_address(ACPI_HANDLE_FWNODE(child),&id);+elseif(is_of_node(child))+err=of_property_read_u32(to_of_node(child),"reg",&id);+if(err){continue;-if(id==dpmac_id)-break;+}elseif(id==dpmac_id){+if(is_of_node(dev->parent->fwnode))+of_node_put(dpmacs);+returnchild;+}}--of_node_put(dpmacs);--returndpmac;+if(is_of_node(dev->parent->fwnode))+of_node_put(dpmacs);+returnNULL;}-staticintdpaa2_mac_get_if_mode(structdevice_node*node,+staticintdpaa2_mac_get_if_mode(structfwnode_handle*dpmac_node,structdpmac_attrattr){phy_interface_tif_mode;interr;-err=of_get_phy_mode(node,&if_mode);-if(!err)-returnif_mode;+err=fwnode_get_phy_mode(dpmac_node);+if(err>0)+returnerr;err=phy_mode(attr.eth_if,&if_mode);if(!err)
@@ -235,26 +250,27 @@ static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {};staticintdpaa2_pcs_create(structdpaa2_mac*mac,-structdevice_node*dpmac_node,intid)+structfwnode_handle*dpmac_node,+intid){structmdio_device*mdiodev;-structdevice_node*node;+structfwnode_handle*node;-node=of_parse_phandle(dpmac_node,"pcs-handle",0);-if(!node){+node=fwnode_find_reference(dpmac_node,"pcs-handle",0);+if(IS_ERR(node)){/* do not error out on old DTS files */netdev_warn(mac->net_dev,"pcs-handle node not found\n");return0;}-if(!of_device_is_available(node)){+if(!of_device_is_available(to_of_node(node))){netdev_err(mac->net_dev,"pcs-handle node not available\n");-of_node_put(node);+of_node_put(to_of_node(node));return-ENODEV;}-mdiodev=of_mdio_find_device(node);-of_node_put(node);+mdiodev=fwnode_mdio_find_device(node);+fwnode_handle_put(node);if(!mdiodev)return-EPROBE_DEFER;
From: Calvin Johnson <hidden> Date: 2021-02-08 17:45:26
Introduce fwnode_mdiobus_register() to register PHYs on the mdiobus.
If the fwnode is DT node, then call of_mdiobus_register().
If it is an ACPI node, then call acpi_mdiobus_register().
Signed-off-by: Calvin Johnson <redacted>
---
Changes in v5: None
Changes in v4:
- Remove redundant else from fwnode_mdiobus_register()
Changes in v3:
- Use acpi_mdiobus_register()
Changes in v2: None
drivers/net/phy/mdio_bus.c | 21 +++++++++++++++++++++
include/linux/phy.h | 1 +
2 files changed, 22 insertions(+)
From: Russell King - ARM Linux admin <linux@armlinux.org.uk> Date: 2021-02-08 17:54:31
On Mon, Feb 08, 2021 at 08:42:42PM +0530, Calvin Johnson wrote:
+int phylink_fwnode_phy_connect(struct phylink *pl,
+ struct fwnode_handle *fwnode,
+ u32 flags)
+{
+ struct fwnode_handle *phy_fwnode;
+ struct phy_device *phy_dev;
+ int ret;
+
+ if (is_of_node(fwnode)) {
+ /* Fixed links and 802.3z are handled without needing a PHY */
+ if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
+ (pl->cfg_link_an_mode == MLO_AN_INBAND &&
+ phy_interface_mode_is_8023z(pl->link_interface)))
+ return 0;
This difference between ACPI and DT really needs to be described in the
commit description.
For example, why is it acceptable to have a PHY in fixed-link mode if
we're using ACPI, and not DT?
If we look at the phylink code, accepting a PHY when in fixed-link mode
is basically not supported... so why should ACPI allow this?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
From: Andy Shevchenko <hidden> Date: 2021-02-08 18:33:23
On Mon, Feb 8, 2021 at 5:14 PM Calvin Johnson
[off-list ref] wrote:
Define acpi_mdiobus_register() to Register mii_bus and create PHYs for
each ACPI child node.
...
+/**
+ * acpi_mdiobus_register - Register mii_bus and create PHYs from the ACPI ASL.
+ *
Redundant blank line.
+ * @mdio: pointer to mii_bus structure
+ * @fwnode: pointer to fwnode of MDIO bus.
+ *
+ * This function registers the mii_bus structure and registers a phy_device
+ * for each child node of @fwnode.
+ */
+int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
+{
+ struct fwnode_handle *child;
+ u32 addr;
+ int ret;
+
+ /* Mask out all PHYs from auto probing. */
+ mdio->phy_mask = ~0;
I would rather see GENMASK(31, 0) here because in case the type of the
variable is changed we will need to amend this anyway.
+ ret = mdiobus_register(mdio);
+ if (ret)
+ return ret;
+ mdio->dev.fwnode = fwnode;
Shouldn't it be rather ACPI_SET_COMPANION() as other bus / drivers do?
+/* Loop over the child nodes and register a phy_device for each PHY */
Indentation.
+ fwnode_for_each_child_node(fwnode, child) {
+ ret = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), &addr);
+ if ((ret) || addr >= PHY_MAX_ADDR)
Too many parentheses.
+ continue;
+
+ ret = fwnode_mdiobus_register_phy(mdio, child, addr);
+ if (ret == -ENODEV)
+ dev_err(&mdio->dev,
+ "MDIO device at address %d is missing.\n",
+ addr);
+ }
+ return 0;
+}
...
+/*
+ * ACPI helpers for the MDIO (Ethernet PHY) API
+ *
+ */
This seems a bit inconsistent with the below.
I see the user of mdiobus_register(). It's the only header should be
included. Everything else would be forward declared like
struct fwnode_handle;
+#if IS_ENABLED(CONFIG_ACPI_MDIO)
+int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode);
+#else /* CONFIG_ACPI_MDIO */
+static inline int acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
+{
+ /*
+ * Fall back to mdiobus_register() function to register a bus.
+ * This way, we don't have to keep compat bits around in drivers.
+ */
+
+ return mdiobus_register(mdio);
+}
+#endif
From: Russell King - ARM Linux admin <linux@armlinux.org.uk> Date: 2021-02-08 18:35:39
On Mon, Feb 08, 2021 at 08:42:42PM +0530, Calvin Johnson wrote:
Define phylink_fwnode_phy_connect() to connect phy specified by
a fwnode to a phylink instance.
Signed-off-by: Calvin Johnson <redacted>
Also, the subject line should be "net: phylink: ..." Consistency is
really appreciated.
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
From: Andy Shevchenko <hidden> Date: 2021-02-08 18:36:13
On Mon, Feb 8, 2021 at 5:15 PM Calvin Johnson
[off-list ref] wrote:
Modify dpaa2_mac_connect() to support ACPI along with DT.
Modify dpaa2_mac_get_node() to get the dpmac fwnode from either
DT or ACPI.
Replace of_get_phy_mode with fwnode_get_phy_mode to get
phy-mode for a dpmac_node.
Use helper function phylink_fwnode_phy_connect() to find phy_dev and
connect to mac->phylink.
...
+ if (is_of_node(dev->parent->fwnode)) {
+ dpmacs = of_find_node_by_name(NULL, "dpmacs");
+ if (!dpmacs)
+ return NULL;
+ parent = of_fwnode_handle(dpmacs);
+ } else if (is_acpi_node(dev->parent->fwnode)) {
From: Russell King - ARM Linux admin <linux@armlinux.org.uk> Date: 2021-02-08 18:37:56
On Mon, Feb 08, 2021 at 08:42:44PM +0530, Calvin Johnson wrote:
Modify dpaa2_mac_connect() to support ACPI along with DT.
Modify dpaa2_mac_get_node() to get the dpmac fwnode from either
DT or ACPI.
Replace of_get_phy_mode with fwnode_get_phy_mode to get
phy-mode for a dpmac_node.
Use helper function phylink_fwnode_phy_connect() to find phy_dev and
connect to mac->phylink.
Signed-off-by: Calvin Johnson <redacted>
I don't think this does the full job.
static int dpaa2_pcs_create(struct dpaa2_mac *mac,
- struct device_node *dpmac_node, int id)
+ struct fwnode_handle *dpmac_node,
+ int id)
{
struct mdio_device *mdiodev;
- struct device_node *node;
+ struct fwnode_handle *node;
- node = of_parse_phandle(dpmac_node, "pcs-handle", 0);
- if (!node) {
+ node = fwnode_find_reference(dpmac_node, "pcs-handle", 0);
+ if (IS_ERR(node)) {
/* do not error out on old DTS files */
netdev_warn(mac->net_dev, "pcs-handle node not found\n");
return 0;
}
- if (!of_device_is_available(node)) {
+ if (!of_device_is_available(to_of_node(node))) {
If "node" is an ACPI node, then to_of_node() returns NULL, and
of_device_is_available(NULL) is false. So, if we're using ACPI
and we enter this path, we will always hit the error below:
@@ -306,7 +321,7 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac) * error out if the interface mode requests them and there is no PHY * to act upon them */- if (of_phy_is_fixed_link(dpmac_node) &&+ if (of_phy_is_fixed_link(to_of_node(dpmac_node)) &&
If "dpmac_node" is an ACPI node, to_of_node() will return NULL, and
of_phy_is_fixed_link() will oops.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
+ /* phy->mii_ts may already be defined by the PHY driver. A
+ * mii_timestamper probed via the device tree will still have
+ * precedence.
+ */
+ if (mii_ts)
+ phy->mii_ts = mii_ts;
Should this be moved out of the if() case?
I'm thinking of the future where we may end up adding mii timestamper
support for ACPI.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
From: Randy Dunlap <rdunlap@infradead.org> Date: 2021-02-08 21:08:36
Hi,
Just a couple of nits below:
On 2/8/21 7:12 AM, Calvin Johnson wrote:
Introduce ACPI mechanism to get PHYs registered on a MDIO bus and
provide them to be connected to MAC.
Describe properties "phy-handle" and "phy-mode".
Signed-off-by: Calvin Johnson <redacted>
---
@@ -0,0 +1,133 @@+.. SPDX-License-Identifier: GPL-2.0++=========================+MDIO bus and PHYs in ACPI+=========================++The PHYs on an MDIO bus [1] are probed and registered using+fwnode_mdiobus_register_phy().++Later, for connecting these PHYs to MAC, the PHYs registered on the
to a MAC,
+MDIO bus have to be referenced.
+
+This document introduces two _DSD properties that are to be used
+for connecting PHYs on the MDIO bus [3] to the MAC layer.
+
+These properties are defined in accordance with the "Device
+Properties UUID For _DSD" [2] document and the
+daffd814-6eba-4d8c-8a91-bc9bbf4aa301 UUID must be used in the Device
+Data Descriptors containing them.
+
+phy-handle
+----------
...
+
+Later, during the MAC driver initialization, the registered PHY devices
+have to be retrieved from the MDIO bus. For this, the MAC driver need
needs
+references to the previously registered PHYs which are provided
+as device object references (e.g. \_SB.MDI0.PHY1).
From: Calvin Johnson <hidden> Date: 2021-02-09 14:37:15
On Mon, Feb 08, 2021 at 12:01:57PM -0800, Randy Dunlap wrote:
Hi,
Just a couple of nits below:
On 2/8/21 7:12 AM, Calvin Johnson wrote:
quoted
Introduce ACPI mechanism to get PHYs registered on a MDIO bus and
provide them to be connected to MAC.
Describe properties "phy-handle" and "phy-mode".
Signed-off-by: Calvin Johnson <redacted>
---
@@ -0,0 +1,133 @@+.. SPDX-License-Identifier: GPL-2.0++=========================+MDIO bus and PHYs in ACPI+=========================++The PHYs on an MDIO bus [1] are probed and registered using+fwnode_mdiobus_register_phy().++Later, for connecting these PHYs to MAC, the PHYs registered on the
to a MAC,
Each PHY is connected to a MAC. So I'll change it to "PHYs to their respective MACs".
quoted
+MDIO bus have to be referenced.
+
+This document introduces two _DSD properties that are to be used
+for connecting PHYs on the MDIO bus [3] to the MAC layer.
+
+These properties are defined in accordance with the "Device
+Properties UUID For _DSD" [2] document and the
+daffd814-6eba-4d8c-8a91-bc9bbf4aa301 UUID must be used in the Device
+Data Descriptors containing them.
+
+phy-handle
+----------
...
quoted
+
+Later, during the MAC driver initialization, the registered PHY devices
+have to be retrieved from the MDIO bus. For this, the MAC driver need
needs
quoted
+references to the previously registered PHYs which are provided
+as device object references (e.g. \_SB.MDI0.PHY1).
+ /* phy->mii_ts may already be defined by the PHY driver. A
+ * mii_timestamper probed via the device tree will still have
+ * precedence.
+ */
+ if (mii_ts)
+ phy->mii_ts = mii_ts;
Should this be moved out of the if() case?
I'm thinking of the future where we may end up adding mii timestamper
support for ACPI.
Right. I'll take case of these in next version.
Thanks
Calvin
From: Calvin Johnson <hidden> Date: 2021-02-15 06:03:09
On Mon, Feb 08, 2021 at 03:31:11PM +0000, Russell King - ARM Linux admin wrote:
On Mon, Feb 08, 2021 at 08:42:42PM +0530, Calvin Johnson wrote:
quoted
+int phylink_fwnode_phy_connect(struct phylink *pl,
+ struct fwnode_handle *fwnode,
+ u32 flags)
+{
+ struct fwnode_handle *phy_fwnode;
+ struct phy_device *phy_dev;
+ int ret;
+
+ if (is_of_node(fwnode)) {
+ /* Fixed links and 802.3z are handled without needing a PHY */
+ if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
+ (pl->cfg_link_an_mode == MLO_AN_INBAND &&
+ phy_interface_mode_is_8023z(pl->link_interface)))
+ return 0;
This difference between ACPI and DT really needs to be described in the
commit description.
For example, why is it acceptable to have a PHY in fixed-link mode if
we're using ACPI, and not DT?
If we look at the phylink code, accepting a PHY when in fixed-link mode
is basically not supported... so why should ACPI allow this?
DT and ACPI should handle fixed-link in similar manner. I'll remove the OF
check.
Thanks
Calvin
From: Calvin Johnson <hidden> Date: 2021-02-15 12:35:00
On Mon, Feb 08, 2021 at 04:28:31PM +0000, Russell King - ARM Linux admin wrote:
On Mon, Feb 08, 2021 at 08:42:44PM +0530, Calvin Johnson wrote:
quoted
Modify dpaa2_mac_connect() to support ACPI along with DT.
Modify dpaa2_mac_get_node() to get the dpmac fwnode from either
DT or ACPI.
Replace of_get_phy_mode with fwnode_get_phy_mode to get
phy-mode for a dpmac_node.
Use helper function phylink_fwnode_phy_connect() to find phy_dev and
connect to mac->phylink.
Signed-off-by: Calvin Johnson <redacted>
I don't think this does the full job.
quoted
static int dpaa2_pcs_create(struct dpaa2_mac *mac,
- struct device_node *dpmac_node, int id)
+ struct fwnode_handle *dpmac_node,
+ int id)
{
struct mdio_device *mdiodev;
- struct device_node *node;
+ struct fwnode_handle *node;
- node = of_parse_phandle(dpmac_node, "pcs-handle", 0);
- if (!node) {
+ node = fwnode_find_reference(dpmac_node, "pcs-handle", 0);
+ if (IS_ERR(node)) {
/* do not error out on old DTS files */
netdev_warn(mac->net_dev, "pcs-handle node not found\n");
return 0;
}
- if (!of_device_is_available(node)) {
+ if (!of_device_is_available(to_of_node(node))) {
If "node" is an ACPI node, then to_of_node() returns NULL, and
of_device_is_available(NULL) is false. So, if we're using ACPI
and we enter this path, we will always hit the error below:
@@ -306,7 +321,7 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac) * error out if the interface mode requests them and there is no PHY * to act upon them */- if (of_phy_is_fixed_link(dpmac_node) &&+ if (of_phy_is_fixed_link(to_of_node(dpmac_node)) &&
If "dpmac_node" is an ACPI node, to_of_node() will return NULL, and
of_phy_is_fixed_link() will oops.
I think of_phy_is_fixed_link() needs to be fixed. I'll add below fix.