Ethernet PHY API Implementation
Description of the Ethernet PHY API
Many Ethernet devices use external (R)MII compliant physical layers (PHYs) to attach themselves to the Ethernet wire. However, some MACs use embedded PHYs and do not have a MII-compliant communication interface. In this case, it may be acceptable to merge the PHY functionality with the MAC device driver, in which case a separate PHY API and configuration structure may not be required. But in the event that an external (R)MII-compliant device is attached to the MAC, the PHY driver must implement the PHY API as follows:
const NET_PHY_API_ETHER NetPHY_API_DeviceName = { NetPhy_Init, (1) NetPhy_EnDis, (2) NetPhy_LinkStateGet, (3) NetPhy_LinkStateSet, (4) 0 (5) };
(1) PHY initialization function pointer
(2) PHY enable/disable function pointer
(3) PHY link get status function pointer
(4) PHY link set status function pointer
(5) PHY interrupt service routine (ISR) handler function pointer
µC/TCP-IP provides code that is compatible with most (R)MII compliant PHYs. However, extended functionality, such as link state interrupts, must be implemented on a per-PHY basis. If additional functionality is required, it may be necessary to create an application specific PHY driver.
Note: It is the PHY driver developers’ responsibility to ensure that all of the functions listed within the API are properly implemented and that the order of the functions within the API structure is correct. The NetPhy_ISR_Handler
field is optional and may be populated as (void *)0
if interrupt functionality is not required.
How to Initialize the PHY
NetPhy_Init()
initializes the PHY driver. It is called by the Ethernet network interface layer after the MAC device driver, if the latter initialized without error.
The PHY initialization function is responsible for the following actions:
- Reset the PHY and wait with timeout for reset to complete. If a timeout occurs, return
perr
set toNET_PHY_ERR_RESET_TIMEOUT
. - Start the auto-negotiation process. This should configure the PHY registers such that the desired link speed and duplex specified within the PHY configuration are respected. It is not required to wait until the auto-negotiation process has completed, as this can take upwards of many seconds. This action is performed by calling the PHY’s
NetPhy_AutoNegStart()
function. - If no errors occur, return
perr
set toNET_PHY_ERR_NONE
.
How to Enable Or Disable the PHY
NetPhy_EnDis()
is called by the Ethernet network interface layer when an interface is started or stopped.
Disabling the PHY will causes the PHY to power down which will cause the link state to be disconnected.
How to Set the Link Speed and Duplex
NetPhy_LinkStateSet()
function sets the current Ethernet link state. Results are passed back to the caller within a NET_DEV_LINK_ETHER
structure which contains fields for link speed and duplex. This function is called by NetIF_Start()
.
How to Specify the Address of the PHY ISR
NetPhy_ISR_Handler()
handles PHY’s interrupts. See section 7-4-7 for more details on how to handle PHY interrupts. μC/TCP-IP does not require PHY drivers to enable or handle PHY interrupts. The generic PHY drivers do not even define a PHY interrupt handler function but instead handle all events by either periodic or event-triggered calls to other PHY API functions.
NetPhy_ISR_Handler()
NetPhy_ISR_Handler() is the physical layer interrupt handler. The PHY ISR handler is called through the network device BSP in a similar manner to that of the device ISR handler. The network device BSP is used to initialize the host interrupt controller, clocks, and any necessary I/O pins that are required for configuring and recognizing PHY interrupt sources. When an interrupt occurs, the first level interrupt handler calls the network device BSP interrupt handler which in turn calls NetIF_ISR_Handler()
with the interface number and interrupt type set to NET_IF_ISR_TYPE_PHY
. The PHY ISR handler should execute the necessary instructions, clear the PHY interrupt flag and exit.
Note: Link state interrupts must call both the Ethernet device driver and Net IF in order to inform both layers of the current link status. This is performed by calling pdev_api->IO_Ctrl()
with the option NET_IF_IO_CTRL_LINK_STATE_UPDATE
as well as a pointer to a NET_DEV_LINK_ETHER
structure containing the current link state speed and duplex. Additionally, the PHY device driver must call NetIF_LinkStateSet()
with a pointer to the interface and a Boolean value set to either NET_IF_LINK_DOWN
or NET_IF_LINK_UP
.
Note: The Generic PHY driver provided with μC/TCP-IP does not support interrupts. PHY interrupt support requires use of the extended PHY registers which are PHY-specific. However, link state is polled periodically by μC/TCP-IP and you can configure the period during compile time.