This page contains some information, tips and tricks that developers can use when porting a new ethernet physical device in STLinux.

By default, the STMMAC device is tested with the Ste100p, Ste101p and SMSC lan8700 physical devices as these are the ones currently available on ST development and reference boards. This guide is for who is trying to use the STMMAC with another physical device.

PHY Abstraction Layer

The Physics Abstraction Layer provides a unified interface to a number of different physics engines. For more information please see Documentation/networking/phy.txt within the kernel source tree.

PHY Device Drivers

With the PHY Abstraction Layer, adding support for new PHYs is quite easy. In some cases, no work is required at all because a Generic PHY driver is already provided.

The Generic driver, by default, works without any interrupts (polling mode). This means that a timer will be used to periodically communicate between the PHY and the STMMAC in order to check the link status. Using an interrupt removes any unnecessary traffic and allows the PHY to signal the STMMAC whenever its state changes. It is therefore recommended that interrupts are used if possible, although using polling normally allows a fast initial hardware bring-up.
Below will be described how to set up PHY interrupts.

At any rate, to write a new PHY driver, you can start by looking at the drivers/net/phy/ste10xp.c (fully tested on ST platforms).

Platform setup

The driver setup information comes from specific platform structures. For example, looking at the arch/sh/boards/st/mb442/setup.c (7109 COCO board's setup file)

In Kernel mb442-2.6.23.17_stm23_0115, the PHY setup is:

static struct plat_stmmacphy_data phy_private_data = {
        .bus_id = 0,
        .phy_addr = 14,
        .phy_mask = 1,
        .interface = PHY_INTERFACE_MODE_MII,
        .phy_reset = &mb442_phy_reset,
};
 
static struct platform_device mb442_phy_device = {
        .name           = "stmmacphy",
        .id             = 0,
        .num_resources  = 1,
        .resource       = (struct resource[]) {
                {
                        .name   = "phyirq",
                        .start  = IRL3_IRQ,
                        .end    = IRL3_IRQ,
                        .flags  = IORESOURCE_IRQ,
                },
        },
        .dev = {
                .platform_data = &phy_private_data,
         }
};

In the phy_private_data structure, phy_addr is the first field to be verified. If a wrong phy address is supplied, then during the kernel boot the STMMAC driver will fail with the following error:

...
0:02 not found
eth0: Could not attach to PHY
stmmac_open: Cannot attach to PHY (error: -19)
...

This shows that the STMMAC is not able to attach the device because the PHY's address 2 on the bus 0 is not found.

phy_addr can also be provided by using the STMMAC as well. To do this, add into the Kernel command line the following option:stmmmaceth="phyaddr:X"

Next in the phy_private_data structure is interface, which defines the physical interface mode used to connect the PHY device.

Physical devices can support several interfaces such us:

  • Media Independent Interface (MII)
  • Reduced Media Independent Interface (RMII)
  • Serial Media Independent Interface (SMII)
  • Gigabit Media Independent Interface (GMII)
  • Reduced Gigabit Media Independent Interface (RGMII)
  • Serial Gigabit Media Independent Interface (SGMII)

The IEEE 802.3u Media Independent Interface (MII) is a standard interface used to connect a Fast Ethernet (i.e. 100Mb/s) MAC-block to a PHY.
RMII reduces the number of signals/pins required for connecting to the PHY from 16 (for an MII-compliant interface) to between 6 and 10.
Gigabit Media Independent Interface (GMII) defines speeds up to 1000 Mbit/s, implemented using an eight bit data interface clocked at 125 MHz, and is backwards compatible with the Media Independent Interface (MII) specification.

The phy_reset entry in the structure allows a software function to be called which controls the PHY hardware reset. In the code above it points to the mb442_phy_reset function which is defined in the board's setup file.

For example, on the MB442 7109 Reference board, the ste100p RESET (pin 28) is wired to the PHY_RESET (from PIO Ports [PIO2_4/mafe_dout]). So the phy reset function directly works on this STPIO line.

System configuration

The STLinux Kernel already contains code to configure the sysconf registers for each SoC. In the board setup file you should ensure that the stx7XXX_configure_ethernet function is invoked appropriately for your board.

For example, in the mb442 setup file, the stx7100_configure_ethernet(0, 0, 0); is invoked as soon as the board is initialized. This function is defined as: stx7100_configure_ethernet(int rmii_mode, int ext_clk, int phy_bus) where:

  • First argument is the MII mode (0: MII, 1: RMII)
  • If the clock is provided through an external device, the ext_clk argument must be set to 1
  • The phy_bus is the physical Id on the bus used by the STMMAC driver during its initialization.

PHY interrupt

The PHY interrupt number has to be set in the platform_device structure. In the case where the driver must work in polling mode (like the "Generic" one) phyirq resource .start and .stop have to be set to -1.

The hardware interrupt level generated by the PHY, whether active-high or active-low, has to match with the software interrupt controller setup. This is done by configuring the external ILC interrupt using the ilc_route_external function.

For example, in the mach.c file for the mb442 board you can see how to program the ILC for routing the external interrupts from the STe101p PHY to the the INTC.

The ilc_route_external parameters are: ilc irq number, routed value and the interrupt level. The latter parameter is how the interrupt is triggered. For PHY interrupt line active low set it to 1, active high 0.
Misconfiguration here means Linux will receive a huge amount of interrupts from the phy.

 
ilc_route_external(ILC_EXT_MDINT, 7, 0);        /* STe100 PHY */

Common HW issues

This section describes commonly reported problems and suggests ways of checking for the causes.

Physical clock frequency setting

The MII interface must be clocked at 25 MHz, while for RMII (as it has half the bus lines) it must be 50MHz. This must be verified before starting.

Usually the (R)MII clock is generated by the ST SoC as this reduces the BOM costs. However, it can also be fed from an external oscillator. The STMicroelectronics Ethernet PHY Module db666 page shows the case of an external clock supplied through the STPIO line. Note: It also reports how to configure PHY pins for the ste101p PHY device to support MII and RMII modes.

External network connection to/from PHY

There are sometimes network problems caused by faulty board layout or problematic network equipment on the ethernet connection side of the PHY (i.e. not the MII, MDIO connection between the PHY and ST SoC).

These can be caused by a number of issues:

  • Incorrect PHY reset
  • Bad board layout between PHY and magnetics (for example: RX and TX are reversed)
  • Incorrect discrete component values are used (check PHY datasheet recommendations)
  • Incompatible magnetics are used (check PHY datasheet recommendations)
  • Board-layout connection between magnetics and RJ45 is incorrect
  • A faulty ethernet lead is being used between RJ45 and external ethernet switch
  • External ethernet switch is faulty

The result of such problems is that there is no network connection and the PHY driver continuously tries to detect the right link. On the kernel system console there will be messages such as:

...
Trying 100/FULL
Trying 10/FULL
...

In case of such problems, it is worth changing the external ethernet cables and ethernet switch first as this sometimes fixes the problem immediately.
If this does not improve things then the board layout between the PHY and external network connection needs to be checked. This usually involves support from the hardware engineering team.

PHY address

The phy address is used for the MDIO interface to manage the transceiver. Depend on the HW layout it is possible to use more then one address. To understand what is the right PHY address you may need to look at the board schematics. You should also verify which pins are connected (some chips use PHYADD[4:0] others PAD[4:0] etc). Some chips may have a dedicated register to maintain the PHY address value.

It is possible to dump the PHY registers and easily understand what is the working phy address. To do this in software, it is necessary to modify the phy device driver. The example below shows how to dump all the registers for the 32 valid PHY addresses. A value of 0xffff for all the registers indicates that the address is invalid.
In the phy_driver structure, .read_status = my_read_status, where my_read_status is defined as:

static int my_read_status(struct phy_device *phydev)
{
	int i, j = 0;
	u32 old_phy_addr = phydev->addr;
	while (j < 32) {
		phydev->addr = j;
		printk(KERN_INFO "PHY Address %d\n", j);
		for (i = 0; i < 32; i++) {
			printk(KERN_INFO " PR%d: 0x%x\n", i, phy_read(phydev, i));
		}
		j++;
		printk(KERN_INFO "\n");
	}
	printk(KERN_INFO "\n");
	phydev->addr = old_phy_addr;
	genphy_read_status(phydev);
	return 0;
}

For more details on PHY registers see the chip datasheet.