Linux Ethernet Offload Engine driver

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

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

 

 

CONFIG_EOE_Image.PNG

 

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 = <&GT_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 32 0>; gt-ctrl-rate-gpios = <&GT_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 0 0>,<&GT_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 1 0>; gt-tx-dpath-gpios = <&GT_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 34 0>; gt-rx-rst-done-gpios = <&GT_WRAPPER_axi_gpio_gt_reset_mask 32 0>; gt-tx-rst-done-gpios = <&GT_WRAPPER_axi_gpio_gt_reset_mask 36 0>; gt-ctrl-rate-gpios = <&GT_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 0 0>,<&GT_WRAPPER_axi_gpio_gt_rate_reset_ctl_0 1 0>; gt-rx-dpath-gpios = <&GT_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)

 

UDP(Gbps)

MTU

TX

CPU (Idle %)

1500

9.56

81.87

RX:

For 1 GRO Port

 

UDP(Gbps)

 

UDP(Gbps)

MTU

RX

CPU (Idle %)

1500

9.56

57.23

For 4 GRO Port

 

UDP(Gbps)

 

UDP(Gbps)

MTU

RX

CPU (Idle%)

1500

9.56

56.46

Versal
Board: VCK190 board (production silicon) + SFP Module

TX:

 

UDP(Gbps)

 

UDP(Gbps)

 

TX

CPU(Idle%)

MTU

9.56

68.78

RX:

For 1 GRO Port

 

UDP(Gbps)

 

UDP(Gbps)

MTU

RX

CPU (Idle%)

1500

9.56

34.98

For 4 GRO Port

 

UDP(Gbps)

 

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)

 

UDP(Gbps)

MTU

TX

CPU (%)

1500

9.55

23.32

RX:

For 1 GRO Port

 

UDP(Gbps)

 

UDP(Gbps)

MTU

RX

CPU (%)

1500

9.55

30.93

For 4 GRO Port

 

UDP(Gbps)

 

UDP(Gbps)

MTU

RX

CPU (%)

1500

9.52

49.29

Versal
Board: VCK190 board (production silicon) + SFP Module

TX:

 

UDP(Gbps)

 

UDP(Gbps)

 

TX

CPU(%)

MTU

9.55

34.45

RX:

For 1 GRO Port

 

UDP(Gbps)

 

UDP(Gbps)

MTU

RX

CPU (%)

1500

9.55

59.79

For 4 GRO Port

 

UDP(Gbps)

 

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 5

Note:

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:

image-20250528-123845.png

 

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 eth0

Note: 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
image-20250528-100121.png

 

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:

image-20250528-124146.png

 

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 5

Server: (Any server machine which connected to client)

iperf3 -s -p 5101 &

Sample Output:

image-20250528-114803.png

 

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 eth0

Note: 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

 

image-20250528-114932.png
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

image-20250528-115628.png

Software Build Instructions:

TBD:

Prerequisites

The below items are required to generate the build files for this system.

  1. Vivado suite for 2025.2 release

  2. Board support package of ZCU102/VCK190 for 2025.2 release

  3. 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_sdt

system-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

Commits
https://github.com/Xilinx/linux-xlnx/commits/xilinx-v2024.2/drivers/net/ethernet/xilinx/xilinx_axienet_eoe.c

Related Links