Linux phylib in the device tree

From SecretLab

Jump to: navigation, search

Here is how to describe MDIO attached Ethernet PHYs in the OpenFirmware device tree:

MDIO devices are listed as child nodes of the MDIO bus. For example, here is an MDIO bus node for the MPC836x-rdx boards:

	mdio@2120 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "fsl,ucc-mdio";
		reg = <0x2120 0x18>;

		phy1: ethernet-phy@1 {
			compatible = "national,DP83848VV";
			reg = <1>;
		};

		phy2: ethernet-phy@2 {
			compatible = "broadcom,BCM5481UA2KMLG";
			reg = <2>;
		};

		phy3: ethernet-phy@3 {
			compatible = "national,DP83848VV";
			reg = <3>;
		};

		phy4: ethernet-phy@4 {
			compatible = "broadcom,BCM5481UA2KMLG";
			reg = <4>;
		};
	};

In the common use case, Ethernet device nodes have a "phy-handle" property which links the Ethernet node to the correct PHY. In other words, the MDIO connection is described by being a child of the MDIO node, the MII data connection is described using a phy-handle property. Here is an Ethernet node from the same board:

	enet2: ucc@2600 {
		compatible = "ucc_geth";
		cell-index = <7>;
		reg = <0x2600 0x200>;
		interrupts = <42>;
		interrupt-parent = <&qeic>;
		rx-clock-name = "clk20";
		tx-clock-name = "clk19";
		phy-handle = <&phy1>;
		phy-connection-type = "mii";
		/* filled by u-boot */
		local-mac-address = [ 00 00 00 00 00 00 ];
	};

MDIO bus drivers can use of_mdiobus_register() to register and create a phy_device for each child node.

Ethernet device drivers can use phylib to do most of the work associated with managing auto-negotiation. In most cases it is sufficient to use of_read_phandle(ethernet-node-pointer, "phy-handle", 0); to get a reference to the PHY device tree node, and then of_phy_connect() and phy_start() to reset and start the PHY state machine, and phylib will call the Ethernet driver's callback whenever the link state changes.

Non PHY devices

Sometimes non-PHY devices get attached to the MDIO bus which cannot be driven by the phylib state machine (ie. Ethernet switches). of_phy_connect() should not be used in this case, and instead the PHY should be accessed directly using the phy_read() and phy_write() functions, and a pointer to the phy_device structure can be obtained with the of_phy_find_device(phy device node) function. The phy device node can be obtained by searching the tree with a helper function like of_find_compatible_node().

Do not reference non-PHY devices with a phy-handle property in an Ethernet node, otherwise the Ethernet driver will attempt to use the device as a normal PHY. Instead fix the speed of the Ethenet device data link (MII, GMII, etc) and drive the non-PHY device with a separate driver. The method for fixing the speed of the Ethernet link is device specific at this point and you'll have to look at the device tree binding documentation for that device.

Personal tools