1. Article purpose[edit | edit source]
This article explains how to configure the Ethernet when it is assigned to the Linux® OS. In this case, it is controlled by the Ethernet framework.
The configuration is performed using the device tree mechanism. This provides a hardware description of the Ethernet peripheral used by the STM32 DWMAC driver.
2. DT bindings documentation[edit | edit source]
The Ethernet is a multifunction device.
Each function is represented by a separate binding document:
3. DT configuration[edit | edit source]
This hardware description is a combination of the STM32 microprocessor device tree files (.dtsi extension) and board device tree files (.dts extension). See the Device tree for an explanation of the device tree file split.
3.1. DT configuration (STM32 level)[edit | edit source]
Ethernet peripheral nodes are located in
- for STM32MP13x lines in stm32mp131.dtsi [3] file,
- for STM32MP15x lines in stm32mp151.dtsi [4] file,
- for STM32MP25x lines in stm32mp251.dtsi [5] file,
- for STM32MP23x lines in stm32mp231.dtsi [6] file,
- for STM32MP21x lines in stm32mp211.dtsi [7] file,
In this file, the status must be set to disabled, and the following properties must be set:
- Physical base address and size of the device register map
- STM32 DWMAC interrupts
- stmmaceth clock and Rx, Tx clocks
This is a set of properties that may not vary for a given STM32MP device, such as: register addresses, interrupts, clocks, ...
For STM32MP15x lines For STM32MP13x lines
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; <&exti 70 IRQ_TYPE_LEVEL_HIGH>; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, interrupt-names = "macirq", "eth_wake_irq"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
For STM32MP25x lines and STM32MP23x lines
eth1: eth1@482c0000 { compatible = "st,stm32mp25-dwmac", "snps,dwmac-5.10a"; reg = <0x482c0000 0x4000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, <&exti1 68 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq", "eth_wake_irq"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "ptp_ref", "ethstp", "eth-ck"; clocks = <&rcc CK_ETH1_MAC>, <&rcc CK_ETH1_TX>, <&rcc CK_ETH1_RX>, <&rcc CK_KER_ETH1PTP>, <&rcc CK_ETH1_STP>, <&rcc CK_KER_ETH1>; st,syscon = <&syscfg 0x3000 0xffffffff>; snps,mixed-burst; snps,pbl = <2>; snps,txqos = <7>; snps,rxqos = <7>; snps,axi-config = <&stmmac_axi_config_1>; snps,tso; access-controllers = <&rifsc 60>; power-domains = <&CLUSTER_PD>; wakeup-source; snps,mtl-rx-config = <&mtl_rx_setup_1>; snps,mtl-tx-config = <&mtl_tx_setup_1>; stmmac_axi_config_1: stmmac-axi-config { snps,wr_osr_lmt = <0x7>; snps,rd_osr_lmt = <0x7>; snps,blen = <0 0 0 0 16 8 4>; }; mtl_rx_setup_1: rx-queues-config { snps,rx-queues-to-use = <2>; queue0 {}; queue1 {}; }; mtl_tx_setup_1: tx-queues-config { snps,tx-queues-to-use = <4>; queue0 {}; queue1 {}; queue2 {}; queue3 {}; }; status = "disabled"; };
eth1: eth1@482c0000 { compatible = "st,stm32mp25-dwmac", "snps,dwmac-5.10a"; reg = <0x482c0000 0x4000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, <&exti1 68 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq", "eth_wake_irq"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "ptp_ref", "ethstp", "eth-ck"; clocks = <&rcc CK_ETH1_MAC>, <&rcc CK_ETH1_TX>, <&rcc CK_ETH1_RX>, <&rcc CK_KER_ETH1PTP>, <&rcc CK_ETH1_STP>, <&rcc CK_KER_ETH1>; st,syscon = <&syscfg 0x3000 0xffffffff>; snps,mixed-burst; snps,pbl = <2>; snps,txqos = <7>; snps,rxqos = <7>; snps,axi-config = <&stmmac_axi_config_1>; snps,tso; snps,mtl-rx-config = <&mtl_rx_setup_1>; snps,mtl-tx-config = <&mtl_tx_setup_1>; stmmac_axi_config_1: stmmac-axi-config { snps,wr_osr_lmt = <0x7>; snps,rd_osr_lmt = <0x7>; snps,blen = <0 0 0 0 16 8 4>; }; mtl_rx_setup_1: rx-queues-config { snps,rx-queues-to-use = <2>; queue0 {}; queue1 {}; }; mtl_tx_setup_1: tx-queues-config { snps,tx-queues-to-use = <4>; queue0 {}; queue1 {}; queue2 {}; queue3 {}; }; status = "disabled"; };
The required and optional properties are fully described in the bindings files.
3.2. Ethernet DT configuration (board level)[edit | edit source]
The device tree board file (.dts) contains all hardware configurations related to board design. The DT node ("ethernet") must be updated to:
- Enable the Ethernet block by setting status = "okay".
- Configure the pins in use via pinctrl, through pinctrl-0 (default pins), pinctrl-1 (sleep pins) and pinctrl-names.
- Configure Ethernet interface used phy-mode = "rgmii"., (rmii, mii, gmii).
- Configure Ethernet max speed max-speed = <1000>"..
Hereafter is an example for MP1x board :
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@1 { reg = <1>; }; }; };
To get info for every board, please refer to board device tree .dts files ( stm32mp1*.dts for MP1x boards[8], or stm32mp2*.dts for MP2x boards[9]) and look for 'ð' keyword.
3.3. DT configuration examples at board level[edit | edit source]
The MP1x example below shows how to configure and enable an Ethernet instance
ðernet0 { status = "okay"; /* enable ethernet0 */ pinctrl-0 = <ðernet0_rmii_pins_a>; /* configure pinctrl modes for ethernet0 */ pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; /* configure ethernet0_rmii_pins_sleep_a as sleep pinctrl configuration for ethernet0 */ pinctrl-names = "default", "sleep"; phy-mode = "rmii"; /* configure ethernet phy mode for ethernet0 */ max-speed = <100>; /* configure ethernet max speed for ethernet0 */ phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@1 { reg = <1>; /* configure ethernet phy @ for ethernet0 */ }; }; };
3.3.1. RMII with Crystal on PHY (Reference clock (standard RMII clock name) is provided by a Phy Crystal)[edit | edit source]
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rmii_pins_a>; pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rmii"; max-speed = <100>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
3.3.2. RMII with 25MHz on ETH_CLK (no PHY Crystal), REF_CLK from PHY (Reference clock (standard RMII clock name) is provided by a PHY)[edit | edit source]
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rmii_pins_a>; pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rmii"; max-speed = <100>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
+ update stm32mp15-pinctrl.dtsi [10] to add ETHCK pin in ethernet0_rmii_pins_* node:
For example:
<STM32_PINMUX('G', 8, AF2)>, /* ETH_RMII_ETHCK */
+ Need to update OP-TEE to generate 25Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P in ed1 board:
update core/arch/arm/dts/stm32mp15xx-edx.dtsi
/* VCO = 594.0 MHz => P = 25, Q = 74, R = 74 */ pll4: st,pll@3 { compatible = "st,stm32mp1-pll"; reg = <3>; cfg = <1 49 23 59 5 PQR(1,1,0) >; };
3.3.3. RMII with 50MHz on ETH_CLK (no PHY Crystal), internal REF_CLK from RCC (Reference clock (standard RMII clock name) is provided by an RCC SoC internal clock)[edit | edit source]
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "eth_wake_irq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,ext-phyclk; snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rmii_pins_a>; pinctrl-1 = <ðernet0_rmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rmii"; max-speed = <100>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
+ update stm32mp15-pinctrl.dtsi to add ETHCK pin in ethernet0_rmii_pins_* node:
For example:
<STM32_PINMUX('G', 8, AF2)>, /* ETH_RMII_ETHCK */
+ Need to update OP-TEE to generate 50Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P in ed1 board:
update core/arch/arm/dts/stm32mp15xx-edx.dtsi
/* VCO = 594.0 MHz => P = 50, Q = 74, R = 74 */ pll4: st,pll@3 { compatible = "st,stm32mp1-pll"; reg = <3>; cfg = < 1 49 11 59 5 PQR(1,1,0) >; };
3.3.4. RGMII with Crystal on PHY, CLK125 from PHY (Reference clock (standard RGMII clock name) is provided by a Phy Crystal)[edit | edit source]
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
3.3.5. RGMII with 25 MHz on ETH_CLK (no PHY Crystal), no CLK125 from PHY (Reference clock (standard RGMII clock name) CLK125 is provided by a RCC SoC internal clock)[edit | edit source]
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
+ update stm32mp15-pinctrl.dtsi to add ETHCK pin in ethernet0_rgmii_pins_* node:
For example:
<STM32_PINMUX('G', 8, AF2)>, /* ETH_RGMII_ETHCK */
+ Need to update OP-TEE to generate 25Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P in ed1 board:
update core/arch/arm/dts/stm32mp15xx-edx.dtsi
/* VCO = 594.0 MHz => P = 50, Q = 74, R = 74 */ pll4: st,pll@3 { compatible = "st,stm32mp1-pll"; reg = <3>; cfg = <1 49 23 59 5 PQR(1,1,0) >; };
3.3.6. RGMII with Crystal on PHY, no 125MHz from PHY[edit | edit source]
ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>, <&exti 70 1>; interrupt-names = "macirq", "eth_wake_irq", "stm32_pwr_wakeup"; clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", "eth-ck", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, <&rcc ETHCK_K>, <&rcc ETHSTP>; st,syscon = <&syscfg 0x4>; snps,mixed-burst; snps,pbl = <2>; snps,en-tx-lpi-clockgating; st,ext-phyclk; snps,axi-config = <&stmmac_axi_config_0>; snps,tso; power-domains = <&pd_core>; status = "disabled"; };
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { reg = <0>; }; }; };
+ update stm32mp15-pinctrl.dtsi to delete CLK125 pin (also no need of ETHCK pin) in ethernet0_rgmii_pins_* node:
+ Need to update OP-TEE to generate 125Mhz clock (from PLL4P or PLL3Q):
for example if PLL4P in ed1 board:
update core/arch/arm/dts/stm32mp15xx-edx.dtsi
4. How to configure a PHY reset signal[edit | edit source]
Some Ethernet PHY allow the use of GPIO to drive the PHY reset.
ðernet0 { status = "okay"; pinctrl-0 = <ðernet0_rgmii_pins_a>; pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; pinctrl-names = "default", "sleep"; phy-mode = "rgmii"; max-speed = <1000>; phy-handle = <&phy0>; mdio0 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0: ethernet-phy@0 { compatible = "ethernet-phy-id0007.c131"; reset-gpios = <&gpioa 4 GPIO_ACTIVE_LOW | GPIO_PULL_UP> reset-assert-us = <1000>; reset-deassert-us = <2000>; reg = <0>; }; }; };
For the kernel update, see "reset-gpios" in Documentation/devicetree/bindings/net/ethernet-phy.yaml[11]
You need to find and replace the value0007.c131 corresponding to your Ethernet PHY: this can be found in the datasheet of the Ethernet PHY, and find the PHY Identifier 1 and PHY Identifier 2 registers.
For a U-Boot with the same syntax of kernel, except for "reset-assert-us" and "reset-deassert-us" properties which are not managed (values of this properties are hardcoded in driver (udelay(2)), the values can be modified with function: eqos_start_resets_stm32 of file: dwc_eth_qos.c[12]
5. How to enable and use Wake on LAN (WoL) from GMAC[edit | edit source]
To perform WoL, Ethernet PHY must have quartz.
From GMAC we can only perform WoL from STOP mode.
To enable wakeup source
ethtool -s eth0 wol g
To wake up board from host:
etherwake -i enp0s25 @MAC_Of_TheBoard
6. How to enable and use Wake on LAN (WoL) from PHY[edit | edit source]
The feature explained in this section is under construction and will be available only with v4.1.0 ecosystem delivery Ethernet 1 of STM32MP135x-DK Discovery kit has the possibility to use Magic Packet to wake up board from Standby mode.
eth1: eth1@5800a000 { compatible = "snps,dwmac-4.20a", "st,stm32mp13-dwmac"; reg = <0x5800a000 0x2000>; reg-names = "stmmaceth"; .... snps,mixed-burst; snps,pbl = <2>; snps,axi-config = <&stmmac_axi_config_0>; snps,tso; '''power-domains = <&pd_core>;''' => to remove to activate WoL from PHY '''wakeup-source;''' => to remove to activate WoL from PHY status = "disabled"; }; ð1 { status = "okay"; pinctrl-0 = <ð1_rmii_pins_a>; pinctrl-1 = <ð1_rmii_sleep_pins_a>; pinctrl-names = "default", "sleep"; phy-mode = "rmii"; max-speed = <100>; phy-handle = <&phy0_eth1>; mdio1 { #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; phy0_eth1: ethernet-phy@0 { compatible = "ethernet-phy-id0007.c131"; reset-gpios = <&mcp23017 9 GPIO_ACTIVE_LOW>; reg = <0>; '''wakeup-source;''' => to add to activate WoL from PHY }; }; };
To enable wakeup source
echo enabled > /sys/devices/platform/soc/5800a000.eth1/mdio_bus/stmmac-0/stmmac-0\:00/power/wakeup
To wake up board from host:
etherwake -i enp0s25 @MAC_Of_TheBoard
Furthermore in OPTEE side, we need to configure a wakeup pin in wakeup source. https://wiki.st.com/stm32mpu/wiki/How_to_configure_PWR_Wake-up_pins
7. How to configure PTP PPS out ?[edit | edit source]
You have possibility to output on GPIO pin a flexible pulse-per-second (PPS) signal.
Need to have PTP clock in your Ethernet device tree:
clock-names = "stmmaceth", "mac-clk-tx", "mac-clk-rx", + "ptp_ref", "ethstp"; clocks = <&rcc ETHMAC>, <&rcc ETHTX>, <&rcc ETHRX>, + <&rcc ETHPTP_K>, <&rcc ETHSTP>; ...
Configure the PPS OUT GPIO pin :
Example for STM32MP13x lines , for Ethernet1 add pin PA4 in devicetree:
eth1_rmii_pins_a: eth1-rmii-1 { pins1 { pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_RMII_TXD0 */ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RMII_TXD1 */ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RMII_TX_EN */ <STM32_PINMUX('A', 1, AF11)>, /* ETH_RMII_REF_CLK */ + <STM32_PINMUX('A', 4, AF10)>, /* PPS OUT */ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */ ...
For others SOC/Boards, refer to documentation (schematic board or pinout board) to find alternate PPS Out pins
Set Flexible PPS frequency :
# echo <idx> <ts> <tns> <ps> <pns> > /sys/class/ptp/ptpX/period
Where, ts/tns is start time and ps/pns is period time, and ptpX is ptp of eth.
WARNING: if several Ethernet instances, ptp0 is not necessarily affected to eth0, to verify which instance is affected to ptp0:
[ 23.709408] stm32-dwmac 5800e000.eth2 eth1: No Safety Features support found [ 23.726093] stm32-dwmac 5800e000.eth2 eth1: IEEE 1588-2008 Advanced Timestamp supported [ 23.748206] stm32-dwmac 5800e000.eth2 eth1: registered PTP clock [ 23.771320] stm32-dwmac 5800e000.eth2 eth1: configuring for phy/rmii link mode [ 23.878828] stm32-dwmac 5800a000.eth1 eth0: PHY [stmmac-0:00] driver [SMSC LAN8742A] (irq=POLL) [ 23.893272] stm32-dwmac 5800a000.eth1 eth0: Register MEM_TYPE_PAGE_POOL RxQ-0 [ 23.914269] dwmac4: Master AXI performs any burst length [ 23.918253] stm32-dwmac 5800a000.eth1 eth0: No Safety Features support found [ 23.942816] stm32-dwmac 5800a000.eth1 eth0: IEEE 1588-2008 Advanced Timestamp supported [ 23.959772] stm32-dwmac 5800a000.eth1 eth0: registered PTP clock [ 23.981629] stm32-dwmac 5800a000.eth1 eth0: configuring for phy/rmii link mode ... # ls -l /sys/class/ptp/ptp0 lrwxrwxrwx 1 root root 0 Nov 7 16:37 /sys/class/ptp/ptp0 -> ../../devices/platform/soc/5800e000.eth2/ptp/ptp0 ==> 5800e000.eth2 is eth1 and have ptp0 as entry
Example to change the duty cycle of the PPS clock for a close to 50% ratio
root@stm32mp1:~# echo "0 0 0 1 1" > /sys/class/ptp/ptp0/period
Entry pps_available is not managed by STMAC driver so stay to 0
root@stm32mp1:~# cat /sys/class/ptp/ptp0/pps_available 0
8. How to configure Ethernet using CubeMX[edit | edit source]
The STM32CubeMX tool can be used to configure the STM32MPU device and get the corresponding platform configuration device tree files.
The STM32CubeMX may not support all the properties described in the above DT bindings documentation paragraph. If so, the tool inserts user sections in the generated device tree. These sections can then be edited to add some properties and they are preserved from one generation to another. Refer to STM32CubeMX user manual for further information.
9. References[edit | edit source]
- ↑ Documentation/devicetree/bindings/net/snps%2Cdwmac.yaml
- ↑ Documentation/devicetree/bindings/net/stm32-dwmac.yaml
- ↑ stm32mp131.dtsi
- ↑ stm32mp151.dtsi
- ↑ stm32mp251.dtsi
- ↑ stm32mp231.dtsi
- ↑ stm32mp211.dtsi
- ↑ MP1x boards
- ↑ MP2x boards
- ↑ arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi , STM32MP15 pinctrl device tree file
- ↑ https://www.kernel.org/doc/Documentation/devicetree/bindings/net/ethernet-phy.yaml, More information
- ↑ https://github.com/u-boot/u-boot/blob/master/drivers/net/dwc_eth_qos.c, More information