Linux Ethernet Offload Engine driver
Ethernet Offload Engine solution is used with Linux AXI Ethernet driver for XXV Ethernet IP on Zynq Ultrascale+ MPSoC
Table of Contents
- 1 HW IP features
- 2 Missing Features and Known Issues/Limitations in Driver
- 3 Kernel Configuration
- 4 Device-tree
- 5 Performance
- 6 Software Build Instructions:
- 6.1.1 TBD:
- 6.1.2 Prerequisites
- 6.1.3 Setup tool chain environment
- 6.2 ZCU102/VCK190:
- 6.2.1 Generate system-top.dts from SDT
- 6.2.2 Petalinux Configuration
- 6.2.3 Rootfs Configuration:
- 6.2.4 Petalinux Build
- 7 Mainline status
- 8 Change Log
- 9 Related Links
Introduction
This page gives an overview of Ethernet Offload Engine Linux driver which is available as part of the AMD Linux distribution.
The EOE driver is included in the AXI Ethernet Linux driver and is currently supported with XXV Ethernet subsystem on Zynq Ultrascale+ MPSoC and MRMAC Ethernet subsystem on Versal.
Paths, files, links and documentation on this page are given relative to the Linux kernel source tree.
HW IP features
For 10G Ethernet Subsystem (XXV)
Supported at 10G speed only
Checksum offload for TX and RX packets
UDP GSO
UDP GRO for multiple channels
UDP packets support ONLY
Built in Memory option up to 4K Bytes for GRO
Auto/ User based Selection for GRO port list
Halt of GRO Merge upon reception of CSUM Error Packets
Statistic Counters for Dropped, CSUM Error Packets
Zero Padding removal for IPv4 packets
Features supported in the driver
Support Checksum Offload
Support Generic Segmentation Offload for UDP packets
Support Generic Receive Offload for multiple channels for UDP packets
Configuring GRO Ports using Ethtool
Missing Features and Known Issues/Limitations in Driver
EOE is not supported with MCDMA driver in the dmaengine framework at the moment.
In Kernel 6.18, High CPU utilization observed during aperf testing on MRMAC+EOE on VCK190 and XXV+EOE on ZCU102 platforms
Missing Features and Known Issues/Limitations in SDT
Kernel Configuration
The following config options should be enabled in order to build the Axi Ethernet driver
CONFIG_ETHERNET
CONFIG_NET_VENDOR_XILINX
CONFIG_XILINX_AXI_EMAC
CONFIG_AXIENET_HAS_MCDMA (Select this option In the design if Axi Ethernet is configured with Axi MCDMA)
CONFIG_XILINX_AXI_EOE=y
Device-tree
For mor details on EOE bindings, please refer to Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml
axi_ethernet_eoe: ethernet@80020000 {
compatible = "xlnx,axi-ethernet-1.00.a";
interrupts = <0>;
clock-names = "s_axi_lite_clk", "axis_clk", "ref_clk", "mgt_clk";
clocks = <&axi_clk>, <&axi_clk>, <&pl_enet_ref_clk>, <&mgt_clk>;
phy-mode = "mii";
reg = <0x80020000 0x10000>,<0x80008000 0x8000>;
reg-names = "mac", "eoe";
phy-handle = <&phy2>;
xlnx,rxmem = <0x800>;
}MRMAC with EOE
xlnx,gtpll and xlnx,gtctrl are replaced with gpios
mrmac@a4011000 {
reg = <0x00 0xa4011000 0x00 0x1000 0x00 0xa40d0000 0x00 0x10000>;
reg-names = "mac", "eoe";
interrupt-names = "mm2s_ch10_introut\0mm2s_ch11_introut\0mm2s_ch12_introut\0mm2s_ch13_introut\0mm2s_ch14_introut\0mm2s_ch15_introut\0mm2s_ch16_introut\0mm2s_ch1_introut\0mm2s_ch2_introut\0mm2s_ch3_introut\0mm2s_ch4_introut\0mm2s_ch5_introut\0mm2s_ch6_introut\0mm2s_ch7_introut\0mm2s_ch8_introut\0mm2s_ch9_introut\0s2mm_ch10_introut\0s2mm_ch11_introut\0s2mm_ch12_introut\0s2mm_ch13_introut\0s2mm_ch14_introut\0s2mm_ch15_introut\0s2mm_ch16_introut\0s2mm_ch1_introut\0s2mm_ch2_introut\0s2mm_ch3_introut\0s2mm_ch4_introut\0s2mm_ch5_introut\0s2mm_ch6_introut\0s2mm_ch7_introut\0s2mm_ch8_introut\0s2mm_ch9_introut";
interrupt-parent = <&gic>;
interrupts = <0x00 0x5d 0x04 0x00 0x5e 0x04 0x00 0x5f 0x04 0x00 0x60 0x04 0x00 0x61 0x04 0x00 0x62 0x04 0x00 0x63 0x04 0x00 0x54 0x04 0x00 0x55 0x04 0x00 0x56 0x04 0x00 0x57 0x04 0x00 0x58 0x04 0x00 0x59 0x04 0x00 0x5a 0x04 0x00 0x5b 0x04 0x00 0x5c 0x04 0x00 0x5d 0x04 0x00 0x5e 0x04 0x00 0x5f 0x04 0x00 0x60 0x04 0x00 0x61 0x04 0x00 0x62 0x04 0x00 0x63 0x04 0x00 0x54 0x04 0x00 0x55 0x04 0x00 0x56 0x04 0x00 0x57 0x04 0x00 0x58 0x04 0x00 0x59 0x04 0x00 0x5a 0x04 0x00 0x5b 0x04 0x00 0x5c 0x04>;
xlnx,channel-ids = "1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","10";
xlnx,num-queues = [00 10];
axistream-connected = <axi_mcdma_0>;
xlnx,addrwidth = <0x20>;
xlnx,mrmac-rate = <25000>;
gt-ctrl-gpios = <>_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 32 0>;
gt-ctrl-rate-gpios = <>_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 0 0>,<>_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 1 0>;
gt-tx-dpath-gpios = <>_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 34 0>;
gt-rx-rst-done-gpios = <>_WRAPPER_axi_gpio_gt_reset_mask 32 0>;
gt-tx-rst-done-gpios = <>_WRAPPER_axi_gpio_gt_reset_mask 36 0>;
gt-ctrl-rate-gpios = <>_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 0 0>,<>_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 1 0>;
gt-rx-dpath-gpios = <>_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 33 0>;
xlnx,axi_mux = <&axi_mux>;
xlnx,has-hw-offload;
xlnx,tx-hw-offload = <0x02>;
xlnx,rx-hw-offload = <0x02>;
};
axi_mux: axi_mux@a40b0000 {
reg = <0x0 0xa40b0000 0x0 0x10000>;
};
axi_mcdma_0 {
compatible = "xlnx,axi-mcdma-1.2", "xlnx,axi-mcdma-1.00.a", "xlnx,eth-dma";
xlnx,addrwidth = /bits/ 8 <0x40>;
....
}
EOE Configured with MCDMA
When Axi EOE is configured with MCDMA, an example device tree node is as follows: (used with MCDMA driver that is internal to Axi Ethernet driver)
ethernet@80020000 {
axistream-connected = <0x42>;
clock-frequency = <0x5f5e100>;
clock-names = "rx_core_clk\0dclk\0s_axi_aclk\0m_axi_mm2s_aclk\0m_axi_s2mm_aclk\0m_axi_sg_aclk\0s_axi_lite_aclk";
clocks = <0x41 0x04 0x48 0x04 0x47 0x40 0x40 0x04 0x47 0x04 0x47>;
compatible = "xlnx,xxv-ethernet-4.1\0xlnx,xxv-ethernet-1.0";
device_type = "network";
local-mac-address = [00 0a 35 00 00 01];
managed = "in-band-status";
phy-mode = "10gbase-r";
reg = <0x00 0x80020000 0x00 0x10000 0x00 0x80008000 0x00 0x8000>;
reg-names = "mac\0eoe";
xlnx,rxmem = <0x40000>;
interrupt-names = "mm2s_ch10_introut\0mm2s_ch11_introut\0mm2s_ch12_introut\0mm2s_ch13_introut\0mm2s_ch14_introut\0mm2s_ch15_introut\0mm2s_ch16_introut\0mm2s_ch1_introut\0mm2s_ch2_introut\0mm2s_ch3_introut\0mm2s_ch4_introut\0mm2s_ch5_introut\0mm2s_ch6_introut\0mm2s_ch7_introut\0mm2s_ch8_introut\0mm2s_ch9_introut\0s2mm_ch10_introut\0s2mm_ch11_introut\0s2mm_ch12_introut\0s2mm_ch13_introut\0s2mm_ch14_introut\0s2mm_ch15_introut\0s2mm_ch16_introut\0s2mm_ch1_introut\0s2mm_ch2_introut\0s2mm_ch3_introut\0s2mm_ch4_introut\0s2mm_ch5_introut\0s2mm_ch6_introut\0s2mm_ch7_introut\0s2mm_ch8_introut\0s2mm_ch9_introut";
interrupt-parent = <0x05>;
interrupts = <0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x59 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04 0x00 0x5a 0x04>;
xlnx,channel-ids = "1\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\010";
xlnx,include-dre;
xlnx,has-hw-offload;
xlnx,rx-hw-offload = <0x02>;
xlnx,tx-hw-offload = <0x02>;
phandle = <0xab>;
mdio {
#address-cells = <0x01>;
#size-cells = <0x00>;
phandle = <0xac>;
};
}; |
Performance
These benchmark performance numbers were obtained by connecting AMD boards to thirdparty NIC cards over Linux PCs/server machines (Ubuntu/Red Hat Enterprise).
The tools used are aperf (Refer to tool information below).
Performance benchmark numbers mentioned in below tables are for reference and dependent on multiple factors i.e. setup , vivado design configuration etc.
NOTE: CPU utilization reported in below performance tables is an aggregate of all CPUs. For ex., on ZynqMP platform, it reports combined utilization of all four A53 cores.
10G Ethernet with AXIMCDMA
2026.1
Kernel version: 6.18
AXI 10G Ethernet Subsystem: TX and RX checksum offload enabled.
ZynqMP
Board: ZCU102 board (production silicon) + SFP Module
TX:
| UDP(Gbps) | |
|---|---|---|
MTU | TX | CPU (Idle %) |
1500 | 9.56 | 81.87 |
RX:
For 1 GRO Port
| UDP(Gbps) | |
|---|---|---|
MTU | RX | CPU (Idle %) |
1500 | 9.56 | 57.23 |
For 4 GRO Port
| UDP(Gbps) | |
|---|---|---|
MTU | RX | CPU (Idle%) |
1500 | 9.56 | 56.46 |
Versal
Board: VCK190 board (production silicon) + SFP Module
TX:
| UDP(Gbps) | |
|---|---|---|
| TX | CPU(Idle%) |
MTU | 9.56 | 68.78 |
RX:
For 1 GRO Port
| UDP(Gbps) | |
|---|---|---|
MTU | RX | CPU (Idle%) |
1500 | 9.56 | 34.98 |
For 4 GRO Port
| UDP(Gbps) | |
|---|---|---|
MTU | RX | CPU (Idle %) |
1500 | 9.56 | 14.08 |
NOTE: EOE Supports 15 Ports for GRO.
Setup Details
Host setup: SuperMicro (H12SSL-NT)
aperf: iperf 3.16 (cJSON 1.7.13)
OS : Ubuntu 20.04.1 LTS (Linux kernel 5.15.0-107-generic)
NIC (Solarflare XtremeScale X2522 10/25GbE Ultra-Low Latency Network Adapter) : Default
2025.1
Kernel version: 6.12
AXI 10G Ethernet Subsystem: TX and RX checksum offload enabled.
ZynqMP
Board: ZCU102 board (production silicon) + SFP Module
TX:
| UDP(Gbps) | |
|---|---|---|
MTU | TX | CPU (%) |
1500 | 9.55 | 23.32 |
RX:
For 1 GRO Port
| UDP(Gbps) | |
|---|---|---|
MTU | RX | CPU (%) |
1500 | 9.55 | 30.93 |
For 4 GRO Port
| UDP(Gbps) | |
|---|---|---|
MTU | RX | CPU (%) |
1500 | 9.52 | 49.29 |
Versal
Board: VCK190 board (production silicon) + SFP Module
TX:
| UDP(Gbps) | |
|---|---|---|
| TX | CPU(%) |
MTU | 9.55 | 34.45 |
RX:
For 1 GRO Port
| UDP(Gbps) | |
|---|---|---|
MTU | RX | CPU (%) |
1500 | 9.55 | 59.79 |
For 4 GRO Port
| UDP(Gbps) | |
|---|---|---|
MTU | RX | CPU (%) |
1500 | 9.56 | 76.58 |
NOTE: EOE Supports 15 Ports for GRO.
Setup Details
Host setup: SuperMicro (H12SSL-NT)
aperf: iperf 3.9 (cJSON 1.7.13)
OS : Ubuntu 20.04.1 LTS (Linux kernel 5.15.0-107-generic)
NIC (Solarflare XtremeScale X2522 10/25GbE Ultra-Low Latency Network Adapter) : Default
Performance Test
Server:
aperf -s -p <Port Number>
Client:
aperf -p <Port Number> -c <SERVER_IP> -b <bandwidth> -u -l <Buffer Length> -G <Packet length>
To check CPU Utilization, use mpstat command
mpstat -P ALL <Intervals> <No of Reports>
ZynqMP UltraScale+
ZCU102 TX Test Commands:
ZCU102 as Tx and Rx as NIC (ex: solarfareNIC server)
Client: (ZCU102)
aperf -i 2 -t 10 -p 5101 -c 192.168.1.20 -b 0M -u -l 65493 -G 1472 & mpstat -P ALL 2 5Note:
In case of Board as Tx, there is an issue in 2024.1 Package where TX Performance is decreasing from 9.57 to 4Gbps by an upstream patch where GSO feature is masked when GSO MAX SIZE is greater than 64K
As a workaround, we are changing the TX aperf command buffer length to 65493 as below.
Server: (Any server machine which connected to client)
iperf3 -s -p 5101 &Sample Output:
ZCU102 RX Test Commands:
For Rx testing, UDP Port number is required by HW GRO configuration. This is configured using the ethtool -N command. This is required for GRO operation to configure EOE hardware to perform GRO association on all data received on a particular UDP Port (up to 15 ports are supported).
Client: Linux PC
aperf -i 2 -t 10 -p 5101 -c 192.168.1.20 -b 0M -u -l 65507 -G 1472 &
Server: ZCU102
Use ethtool utility for each Ethernet interface listed by ifconfig to determine which Ethernet (eth0 as example below) interface is connected to EOE IP and associated with xaxienet driver
ethtool -i eth0Note: To achieve the max performance, before launching the aperf server run below commands to increase the net core read window sizes and change the BD size to 256
sudo sysctl -w net.core.rmem_default=8388608
sudo sysctl -w net.core.rmem_max=8388608 # 8MB Window size
Change buffer descriptor size
ifconfig <interface> down
ethtool -G <interface> rx 256 # to change BD size to 256
ifconfig <interface> up
ifconfig eth0 192.168.1.100# Assign interrupt affinity to CPU for NAPI event handling interrupt calls (for Tx and Rx). In below example IRQ52 and 53 are assigned to eth0
cat /proc/interrupts
echo 2 > /proc/irq/51/smp_affinity # echo 2 = 010 which maps to CPU1
echo 2 > /proc/irq/52/smp_affinity # echo 2 = 010 which maps to CPU1
ethtool -N eth0 flow-type udp4 dst-port 5101 #Should match -p port parameter on client
taskset -c 0 ./aperf -s -p 5101 & mpstat -P ALL 2 5
Sample Output:
Versal :
VCK190 TX Commands:
VCK190 as Tx and Rx as NIC (ex: solarfareNIC server)
Client: (VCK190)
aperf -i 2 -t 10 -p 5101 -c 192.168.1.20 -b 0M -u -l 65493 -G 1472 & mpstat -P ALL 2 5Server: (Any server machine which connected to client)
iperf3 -s -p 5101 &Sample Output:
VCK190 RX Commands:
Client: Linux PC
aperf -i 2 -t 10 -p 5101 -c 192.168.1.20 -b 0M -u -l 65507 -G 1472 &Server: VCK190
Use ethtool utility for each Ethernet interface listed by ifconfig to determine which Ethernet (eth0 as example below) interface is connected to EOE IP and associated with xaxienet driver
ethtool -i eth0Note: To achieve the max performance, before launching the aperf server run below commands to increase the net core read window sizes and change the BD size to 256
sudo sysctl -w net.core.rmem_default=8388608
sudo sysctl -w net.core.rmem_max=8388608 # 8MB Window size
Change buffer descriptor size
ifconfig <interface> down
ethtool -s <interface> speed 10000 # switch to 10G
ethtool -G <interface> rx 256 # to change BD size to 256
ifconfig <interface> up
ifconfig <interface> 192.168.1.100
# Assign interrupt affinity to CPU for NAPI event handling interrupt calls (for Tx and Rx). In below example IRQ14 to IRQ29 are assigned to eth0
cat /proc/interrupts
echo 2 > /proc/irq/14/smp_affinity
echo 2 > /proc/irq/15/smp_affinity
echo 2 > /proc/irq/16/smp_affinity
echo 2 > /proc/irq/17/smp_affinity
echo 2 > /proc/irq/18/smp_affinity
echo 2 > /proc/irq/19/smp_affinity
echo 2 > /proc/irq/20/smp_affinity
echo 2 > /proc/irq/21/smp_affinity
echo 2 > /proc/irq/22/smp_affinity
echo 2 > /proc/irq/23/smp_affinity
echo 2 > /proc/irq/24/smp_affinity
echo 2 > /proc/irq/25/smp_affinity
echo 2 > /proc/irq/26/smp_affinity
echo 2 > /proc/irq/27/smp_affinity
echo 2 > /proc/irq/28/smp_affinity
echo 2 > /proc/irq/29/smp_affinity
ethtool -N eth0 flow-type udp4 dst-port 5101 #Should match -p port parameter on client
taskset -c 0 ./aperf -s -p 5101 & mpstat -P ALL 2 5
Sample Output
Software Build Instructions:
TBD:
Prerequisites
The below items are required to generate the build files for this system.
Vivado suite for 2025.2 release
Board support package of ZCU102/VCK190 for 2025.2 release
Hardware required: ZCU102 rev1.0 board / VCK190 Board.
Setup tool chain environment
Please source the following scripts for tool chain environment.
A. source <2025.2_Vivado>/settings64.sh
B. source <2025.2_Vitis>/settings.sh
C. source <2025.2_Petalinux>/settings.sh
ZCU102/VCK190:
Generate system-top.dts from SDT
source vitis (source <2025.2_Vitis>/settings.sh)
Enter xsct command and it will enter xsct% terminal
In xsct% terminal give SDTGEN set_dt_param command to give input as design file(.xsa) and output directory
Generate xsa from 2025.2 example design
sdtgen set_dt_param -xsa <.xsa path> -dir <outdirectory_name>Run SDTGEN generate_sdt command to generate device tree and copy date into <out directory>
sdtgen generate_sdtsystem-top.dts will be in out directory
Petalinux Configuration
source <2025.2_Petalinux>/settings.sh
petalinux-config --get-hw-description=<path to system-top.dts>Rootfs Configuration:
petalinux-config -c rootfs
#Enable below tools for performance measurement
Taskset (Filesystem Packages → base → util-linux)
Ethtool (Filesystem Packages -> console -> network -> ethtool)
mpstat (Filesystem Packages -> console -> utils -> systat)Aperf <Add github link> ?
Petalinux Build
petalinux-build
Mainline status
The EOE driver is currently NOT in mainline
Change Log
2026.1
Rebased on mainline kernel 6.18
aux_mux gpio is added for reset/speed handling for MRMAC
Commits
History for drivers/net/ethernet/xilinx/xilinx_axienet_eoe.c - Xilinx/linux-xlnx
2025.1
Rebase existing eoe patches on kernel 6.12.
Fix Segmentation Faults and Null Pointer Deference for skb when multiple interfaces are used.
Configure GRO Destination Address when ifconfig down and up is done.
Updates coalesce count for EOE TX and RX for better Throughput.
Fix reading of "xlnx,addrwidth" DT property.
To Align mainline, handle ndo_features for IPV6 and IPV4 CSUM Feature.
Commits
History for drivers/net/ethernet/xilinx/xilinx_axienet_eoe.c - Xilinx/linux-xlnx
2024.1
First release adds Support for Ethernet Offload Engine. Generic Segmentation Offload, and multi-port Generic Receive Offload