A tale of two drivers
In the last year two customers asked us to add support for a new IEEE 802.3 Clause 45 PHY for use with a network interface in their existing system. One customer was a QNX user, the other was a VxWorks user. These RTOSes take a different approach to network interface management, which dictated the approach we took.
This article isn’t a Clause 45 primer but it will be useful to take a quick overview and give some definitions so the jargon doesn’t get in the way.
IEEE 802.3 Clause 22
The physical layer device (PHY) is responsible for putting the packet data produced by the media access controller (MAC), aka the Ethernet controller, on to the transmission line (coaxial cable, twisted pair, CAT-5 cable, fibre optic cable, etc.). IEEE 802.3 Clause 22 describes how this should work. This includes the medium independent interface (MII) used to access the PHY registers to configure the PHY and get back status information, such as link status. More accurately this is the management data I/O interface (MDIO) although many people use MII and MDIO interchangeably.
The MII allows for 32 PHYs to be connected to the MDIO. Each PHY provides a standard set of registers in a 5-bit address space, i.e. up to 32 registers. This was sufficient for 10/100 Mbit/s devices but as PHYs became more sophisticated, speeds increased and different media emerged, manufacturers needed more registers for configuration and initialisation, status and error reporting, and fine tuning and calibration.
IEEE Clause 45
IEEE 802.3 clause 45 defines a new addressing scheme that expands the PHY addressing scheme as follows:
- up to 32 PHY devices on the MDIO (same as Clause 22)
- each PHY device can consist of 32 MDIO manageable devices (MMD), including two vendor-specific MMD
- each MMD has a 16-bit address space, i.e. up to 65536 registers
- If the standard Clause 22 registers are present they are in MMD 0.
When this was first introduced it was assumed that the MAC would talk Clause 45 to PHY and all would be well. However, people then wanted (quite reasonably) to connect these newer Clause 45 PHYs to their standard (Clause 22) MAC. How would this work?
Clause 45 registers via Clause 22
The answer was provided by the following proposal: Clause 22 Access to Clause 45 Registers. The mechanism uses an indirect register access method and is clearly explained in the proposal so I won’t go into details. In essence, it works like this:
- Clause 22 Register 13 is used to:
- identify which MMDs is being addressed
- Define the operation being performed (read or write)
- Clause 22 Register 14 is used to:
- set the address of the Clause 45 register in the MMD
- Set data to write to the register
- Get data read from the register
So what’s the big deal? Clause 45 defines standard registers and features but provides plenty of latitude for PHY vendors to implement their own registers and operations. I guess this is providing their “value-add” so customers will buy their PHY devices. From a software point of this is a way of making a device that is nominally adhering to a standard behave in a very non-standard way and be a pain to support.
Crucially, a Clause 45 PHY does not have to provide the standard 22 register set (other than registers 13 and 14) that would allow existing software to use it, albeit with some reduced functionality.
Now we can get back to some specifics.
QNX PHY device management
A QNX Ethernet driver manages the MAC but also:
- Determines what media are supported by the PHY and advertises them to the network stack
- Provides routines for accessing PHY registers via the MDIO
- Manages PHY initialisation, configuration and status reporting
The Ethernet driver is helped in this endeavour by the QNX MII management library. This provides a device independent API for performing some standard operations such as:
- Resetting the PHY
- Setting the PHY mode (auto-negotiation mode or fixes speed/duplex)
- Starting link auto-negotiation
- Getting auto-negotiation results
- Getting link status (link up or down)
This avoids duplicating this functionality in every Ethernet driver.
VxWorks PHY device management
VxWorks takes a different approach. The Ethernet driver has to provide methods for reading and writing the PHY registers via the MDIO. However, the PHY management is performed by an independent PHY driver, which:
- Advertises the supported media to the network stack
- Manages PHY initialisation, configuration and status reporting
- Sets the PHY mode (10/100 Mbit/s or 1000 Mbit/s)
- Starts link auto-negotiation
- Provides link status
For many PHY devices the generic PHY driver is sufficient for them to operate correctly and pass data to/from the MAC. Generally, the MAC just needs to know the PHY mode (to set up clocking and data path) and the link state (to let the network stack know when data can be sent).
Marvell and Broadcom PHYs are notable exceptions. They often require device-specific drivers to perform complicated and proprietary initialisation steps and get status information from non-standard registers in addition to the well-defined Clause 22 registers.
RTOS support for Clause 45
Recent versions of QNX and VxWorks have added some support for managing Clause 45 PHYs. QNX SDP 7.1 includes a Clause 45 version of their MII management library that uses the Clause 22 to Clause 45 indirect register access mechanism. This includes support for a small handful of Clause 45 PHYs. However, I had to glean this from the MII header files as the documentation does not explain this.
The difficulty comes in using this library to support a new device that needs a vendor-specific initialisation sequence or provides status via vendor-specific registers, or does anything that is outside what is defined by Clause 45. A standard QNX development licence does not provide source code for the OS libraries so the options are:
- Get a source licence and update the MII library yourself
- Get Blackberry consulting service to do it
- Put the PHY driver support into the MAC driver
Clause 45 PHY management: a data driven approach
Our QNX client didn’t want to do any of the above. They wanted a solution that was both extensible and didn’t involve writing new code to add support for additional devices. In fact, they proposed a data-driven approach that defined the following attributes for PHY:
- Device Id (register 2 and 3)
- Registers (and access sequence) to set the link speed
- Registers (and access sequence) to read to get link speed
- Registers and values to set to initialise the device
Adding support for a new device in the future would simply require a new entry in the PHY attribute table.
The key to making this work was to emulate a Clause 22 PHY that could be managed by the QNX MII management library just like a read Clause 22 PHY. When the MII management library accessed a standard Clause 22 PHY register our code accessed the necessary Clause 45 PHY registers and turned the data into a value that was returned to management library.
Time will tell how extensible this approach really is but I was reasonably pleased with the outcome.
It’s just a driver
The VxWorks solution was quite different for the following reasons:
- kernel and device driver source code is provided with a standard development licence
- VxWorks has a PHY driver model that defines methods and responsibilities
- VxWorks 7 includes support for Clause 45 register indirection via Clause 22 registers 13 and 14
In other words all we had to do was write a new PHY driver and the VxWorks VxBus driver framework took care making it accessible to the MAC driver.
It also makes for a dull narrative: man writes driver.
The odd thing is that the QNX network stack is based on the NetBSD network stack which does have the concept of a PHY driver. It’s not clear why this was not incorporated into QNX but maybe if I had a source licence things would have looked different.