SNLA450 July   2024 DP83822H , DP83822HF , DP83822I , DP83822IF , DP83826E , DP83826I , DP83848-EP , DP83848Q-Q1 , DP83867CR , DP83867CS , DP83867E , DP83867IR , DP83867IS , DP83TC812R-Q1 , DP83TC812S-Q1 , DP83TC813R-Q1 , DP83TC813S-Q1 , DP83TC814R-Q1 , DP83TC814S-Q1 , DP83TG720R-Q1 , DP83TG720S-Q1 , DP83TG721S-Q1

 

  1.   1
  2.   Abstract
  3.   Trademarks
  4. 1Texas Instruments Ethernet PHY Drivers
  5. 2Ethernet PHY Driver Overview
    1. 2.1 Exploring Linux Driver Types
      1. 2.1.1 U-Boot Driver
      2. 2.1.2 Kernel Driver
  6. 3Driver Integration
    1. 3.1 Linux Device Tree
    2. 3.2 Integrating Driver
  7. 4Common Terminal Commands
    1. 4.1 Initialization Commands
      1. 4.1.1 dmesg | grep -i mdio
      2. 4.1.2 ifconfig
    2. 4.2 Functional Commands
      1. 4.2.1 Phytool
      2. 4.2.2 Ethtool
      3. 4.2.3 Forced Master/Slave
    3. 4.3 Diagnostic Commands
      1. 4.3.1 SQI
      2. 4.3.2 TDR
      3. 4.3.3 Throughput Testing - Ping and iPerf
  8. 5Summary
  9. 6References

Linux Device Tree

A Linux device tree is a data structure used to describe the hardware components and configuration in embedded systems. The device tree provides a standardized way for the operating system to understand the hardware layout, including details about the processor, memory, buses. and peripherals. Device tree data is typically stored in a binary format (.dtb file) and is passed to the Linux kernel during boot-up. The kernel then uses this information to dynamically bind device tree nodes and initialize hardware components, allowing for efficient and flexible hardware support across different embedded platforms without the need for hard-coding hardware details into the kernel.

The Device Tree Codeblock is an example of how four Ethernet PHYs on the daughter card are configured in the device tree file. CPSW refers to the MAC interface of the processor and the main node definitions to consider are:

  • &cpsw0 {} which initializes four RGMII interfaces
  • cpsw0_portn {} which initializes further details for each port
    • phy-mode: sets the MAC interface of that port
    • phy-handle: defines how to set up the PHY
      • <&cpsw9g_phyx> is used to set the PHY Address
        • Note that x does not set the PHY Address and is only a naming convention. The address is assigned lower in the Device Tree Codeblock, inside the cpsw9g_mdio{} definition.
          • reg = <x>;
      • RGMII delays can be set here too, an example can be seen in the J721E common processor board dts file, line 744, and in the RGMII Codeblock.
        • Typically our RGMII delay recommendation is to configure the PHY to delay both TX and RX CLK by 2.0ns (referred to as shift mode), while the processor is set to 0 delay (referred to as align mode). See Table 3-1 for more information.
          • However, many TI processors have an internal 2.0ns delay on the TX lines that cannot be disabled. In the RGMII Codeblock, only RX delay is configured on the PHY for this reason.
    • phys
      • Setting which eth# each port is assigned
        • <&cpsw0_phy_gmii_sel n>
Table 3-1 RGMII Shift Configurations
MAC Configuration Required PHY Configuration
Align on RX Shift on RX
Shift on RX Align on RX
Align on TX Shift on TX
Shift on TX Align on TX

RGMII Codeblock:

&davinci_mdio {
	phy0: ethernet-phy@0 { //PHY0 is defined and passed to phy-handle
		reg = <0>;
		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
	};
};

&cpsw_port1 {
	phy-mode = "rgmii-rxid";
	phy-handle = <&phy0>;
};

Device Tree Codeblock:

&cpsw0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&mdio_pins_default
             &rgmii1_pins_default
             &rgmii2_pins_default
             &rgmii3_pins_default
             &rgmii4_pins_default
             >;
};

&cpsw0_port1 {
    phy-handle = <&cpsw9g_phy0>;
    phy-mode = "rgmii-rxid";
    mac-address = [00 00 00 00 00 00];
    phys = <&cpsw0_phy_gmii_sel 1>;
};

&cpsw0_port2 {
    phy-handle = <&cpsw9g_phy4>;
    phy-mode = "rgmii-rxid";
    mac-address = [00 00 00 00 00 00];
    phys = <&cpsw0_phy_gmii_sel 2>;
};

&cpsw0_port3 {
    phy-handle = <&cpsw9g_phy5>;
    phy-mode = "rgmii-rxid";
    mac-address = [00 00 00 00 00 00];
    phys = <&cpsw0_phy_gmii_sel 3>;
};

&cpsw0_port4 {
    phy-handle = <&cpsw9g_phy8>;
    phy-mode = "rgmii-rxid";
    mac-address = [00 00 00 00 00 00];
    phys = <&cpsw0_phy_gmii_sel 4>;
};
&cpsw9g_mdio {
	bus_freq = <1000000>;
	#address-cells = <1>;
	#size-cells = <0>;

	cpsw9g_phy0: ethernet-phy@0 {
		reg = <0>;
	};
	cpsw9g_phy4: ethernet-phy@4 {
		reg = <4>;
	};
	cpsw9g_phy5: ethernet-phy@5 {
		reg = <5>;
	};
	cpsw9g_phy8: ethernet-phy@8 {
		reg = <8>;
	};
};

When the board is running, the terminal command dmesg grep | mdio can be used to confirm the PHY address (phy[x]) and eth port (ethn).

davinci_mdio c000f00.mdio: phy[0]: device c000f00.mdio:00, driver TI DP83TG720CS1.1
davinci_mdio c000f00.mdio: phy[4]: device c000f00.mdio:04, driver TI DP83TG721CS1.0
davinci_mdio c000f00.mdio: phy[5]: device c000f00.mdio:05, driver TI DP83TC812CS2.0
davinci_mdio c000f00.mdio: phy[8]: device c000f00.mdio:08, driver TI DP83TC814CS2.0
am65-cpsw-nuss c000000.ethernet eth4: PHY [c000f00.mdio:08] driver [TI DP83TC814CS2.0] (irq=POLL)
am65-cpsw-nuss c000000.ethernet eth3: PHY [c000f00.mdio:05] driver [TI DP83TC812CS2.0] (irq=POLL)
am65-cpsw-nuss c000000.ethernet eth2: PHY [c000f00.mdio:04] driver [TI DP83TG721CS1.0] (irq=POLL)
am65-cpsw-nuss c000000.ethernet eth1: PHY [c000f00.mdio:00] driver [TI DP83TG720CS1.1] (irq=POLL)