![]() |
![]() |
The PHY driver is a submodule of the CPSW low-level driver (LLD) dedicated to Ethernet PHY management. It implements a state machine required to handle the lifecycle of PHYs, from initialization to link establishment.
The PHY submodule interacts with the MDIO submodule to perform operations like detecting alive and/or linked PHYs, and for PHY register accesses. The relationship between PHY, MDIO and CPSW integration layer is shown below.
Currently, the PHY driver supports only Clause-22 devices. Clause-45 devices are not supported.
The top-layer of PHY driver is located at <CPSW_LLD>/src/cpsw_phy.c
. This layer implements the basic APIs that are needed to communicate with the CPSW integration layer, namely CpswPhy_open()
, CpswPhy_ioctl()
and CpswPhy_close()
.
The CPSW_LLD is capable of supporting multiple PHYs running simultaneously; each PHY has its own driver instance, its own state machine and hence will follow independent lifecycle from other PHYs.
The lifecycle of the PHYs is handled by the PHY driver via a state machine implementation. This state machine is composed of the following states:
The diagram in the figure below provides a simplified view of the state transitions of the PHY state machine.
Refer to Appendix A for a more detailed view of the PHY state machine.
The PHY driver model has been designed to partition device-specific operations from device-agnostic common operations. The former are implemented by PHY device specific drivers, while the latter can be carried out directly by the main PHY driver.
This model facilitates the addition of new drivers for PHY devices not yet supported in the CPSW_LLD. The CpswPhy_Drv
structure is defined as the interface that device specific drivers must implement. Since this structure is not exposed to the application, its scope is internal to the CPSW LLD.
The members of the CpswPhy_Drv
structure can be mandatory or optional in nature. Optional members can be set to NULL if the PHY doesn't provide an implementation for them. The list below provides a description of the purpose of each CpswPhy_Drv
member.
NULL
.NULL
.reset()
function has completed. If reset()
is provided, isResetComplete()
must be provided as well.NULL
.The current version of CPSW LLD includes two PHY drivers: generic PHY and DP83867.
The generic PHY driver is a special case because its implementation is limited to IEEE-Standard MII registers. Reuse of PHY generic function by other device-specific drivers is possible when their CpswPhy_Drv
implementation doesn't deviate from standard. The diagram in figure below shows the reuse of extended register read/write functions by the DP83867 driver.
Device specific drivers can be found at <CPSW_LLD>/src/phy/*
.
The PHY-to-driver binding is the process of selecting the best driver for a PHY device based on the device's unique identifier. This process is done by the main PHY driver upon alive detection of a PHY device and takes place in the FINDING state.
The device unique identifier is read from PHYIDR1 and PHYIDR2 registers and populated into a structure of type CpswPhy_Version.
The main PHY driver has a CpswPhy_drvs
array which contains all device specific drivers that are registered and that will participate in the search for the best driver for the PHY that had been recently discovered.
In the search process, the main PHY driver will call the isPhyDevSupported()
function of each registered driver. The drivers will use the CpswPhy_Version which is passed as an argument in order to determine whether the device is supported or not. If it is, isPhyDevSupported()
must return true
and the search process ends. If not, the search continues with the next registered device.
The generic PHY (which must be the last one in the CpswPhy_drvs
array) will be bound to the device if no other driver can support a given PHY, but the PHY full functionality can't be guaranteed.
The following list of steps is provided as guideline when adding a new PHY driver for a device which is not supported by CPSW LLD.
<CPSW_LLD>/include
.<CPSW_LLD>/src/phy
. CpswPhy_Drv
, but don't make it static. This variable will be later accessed as an extern symbol by the CPSW PHY driver.CpswPhy_Drv
structure with the function pointers of the device specific implementation.CpswPhy_Drv
as extern in main PHY driver located at <CPSW_LLD>/src/cpsw_phy.c
. Also, add it to the CpswPhy_drvs
array.SRCS_COMMON
in the CPSW driver makefile locate at <CPSW_LLD>/src/makefile
.SRCDIR
, so just the source name needs to be added.Detailed view of the PHY state machine.