Gennaro Cimmino c22686329b realtek: eth: support changing the MTU
Add a change_mtu operation, so the length the switch may deliver to the
CPU follows the conduit MTU instead of keeping the value programmed when
the interface came up.

To avoid trouble with the receive buffer, adapt the head of line budget
along with it. Those registers limit how many packets the hardware may
append to a receive ring, and deriving that limit from a frame of
maximum length makes the smallest MTU pay the price of the largest. With
400 byte fragments a 1626 byte frame occupies five of them, which leaves
128 / 5 = 25 packets per ring, while the 1530 byte frame of a tagged
conduit at its idle MTU needs four and fits 32.

The two limits move in opposite directions, so the order matters: on the
way up the budget shrinks before the switch is allowed to hand over
larger frames, which keeps the ring from ever running a budget meant for
smaller ones. On the way down it grows only after the switch has stopped
handing over the larger frames, which narrows that window rather than
closing it, as the ring may still hold frames of the previous size. The
pair runs under the lock the rest of the driver programs those registers
with, as the transmit watchdog is not serialised against an MTU change.
The budget comes from the config, one function per family, and opening
the interface calls it too: RTL83xx has none to resize, as its rings are
free floating, so it writes the ring size of zero that its reset paths
used to write themselves.

Nothing else has to follow, as the receive buffers are of a fixed size.
The largest MTU comes from the config too, one value per family: 10000
bytes on RTL838x and 12288 on the others, less the frame overhead. Those
are the limits the DSA driver already declares in its rmon ranges. A
frame must also fit into a single skb, whose linear part and fragments
hold 400 bytes each, so the operation refuses above an MTU of 7174 on
every family, well below what the switches would take. The fragment
size carries a TODO of its own, and raising it lifts that bound towards
the hardware one.

That remaining window is why every accepted change carries a warning. A
closed interface has neither a ring to protect nor registers worth
touching, as opening it derives both limits from the MTU anyway, so
leave the hardware alone while it is down. That also keeps the warning
out of the boot log, where dsa_conduit_setup() sets the tagging overhead
on a conduit that carries no traffic yet.

Tested on an RTL9303 (Hasivo S1100W-8XGT-SE, RTL8264B PHY, USXGMII).
Both limits follow every MTU as computed, read back from the switch:

  conduit MTU   1504   1000   7174
  packet length 1530   1026   7200
  packets/ring    32     42      7

where the previous static sizing programmed 25 packets per ring at every
MTU. An MTU of 7175 is refused, and one of 9000, which the family
ceiling would allow, reaches the operation and is refused there: no
warning is logged for it, where an accepted change logs one, and the
boot log carries none at all. Raising the MTU to 1600 while the
interface is down leaves the registers at 1530 and the budget at 32
packets and logs nothing, while bringing it up afterwards programs 1626
and 25, so the change is deferred rather than lost. Traffic keeps
flowing across the changes: a 102 byte frame is answered five times out
of five at each step, while a 1046 byte one passes at MTU 1504, stops at
MTU 1000, whose limit of 1026 it exceeds, and passes again once the MTU
is back. Sixty alternating changes between two MTUs complete with
nothing logged, on a build with spinlock debugging enabled.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/24421
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
2026-07-28 16:25:33 +02:00
…
…
…

OpenWrt logo

OpenWrt Project is a Linux operating system targeting embedded devices. Instead of trying to create a single, static firmware, OpenWrt provides a fully writable filesystem with package management. This frees you from the application selection and configuration provided by the vendor and allows you to customize the device through the use of packages to suit any application. For developers, OpenWrt is the framework to build an application without having to build a complete firmware around it; for users this means the ability for full customization, to use the device in ways never envisioned.

Sunshine!

Download

Built firmware images are available for many architectures and come with a package selection to be used as WiFi home router. To quickly find a factory image usable to migrate from a vendor stock firmware to OpenWrt, try the Firmware Selector.

If your device is supported, please follow the Info link to see install instructions or consult the support resources listed below.

An advanced user may require additional or specific package. (Toolchain, SDK, ...) For everything else than simple firmware download, try the wiki download page:

Development

To build your own firmware you need a GNU/Linux, BSD or macOS system (case sensitive filesystem required). Cygwin is unsupported because of the lack of a case sensitive file system.

Requirements

You need the following tools to compile OpenWrt, the package names vary between distributions. A complete list with distribution specific packages is found in the Build System Setup documentation.

binutils bzip2 diff find flex gawk gcc-6+ getopt grep install libc-dev libz-dev
make4.1+ perl python3.8+ rsync subversion unzip which

Quickstart

  1. Run ./scripts/feeds update -a to obtain all the latest package definitions defined in feeds.conf / feeds.conf.default

  2. Run ./scripts/feeds install -a to install symlinks for all obtained packages into package/feeds/

  3. Run make menuconfig to select your preferred configuration for the toolchain, target system & firmware packages.

  4. Run make to build your firmware. This will download all sources, build the cross-compile toolchain and then cross-compile the GNU/Linux kernel & all chosen applications for your target system.

The main repository uses multiple sub-repositories to manage packages of different categories. All packages are installed via the OpenWrt package manager called opkg. If you're looking to develop the web interface or port packages to OpenWrt, please find the fitting repository below.

  • LuCI Web Interface: Modern and modular interface to control the device via a web browser.

  • OpenWrt Packages: Community repository of ported packages.

  • OpenWrt Routing: Packages specifically focused on (mesh) routing.

  • OpenWrt Video: Packages specifically focused on display servers and clients (Xorg and Wayland).

Support Information

For a list of supported devices see the OpenWrt Hardware Database

Documentation

Support Community

  • Forum: For usage, projects, discussions and hardware advise.
  • Support Chat: Channel #openwrt on oftc.net.

Developer Community

License

OpenWrt is licensed under GPL-2.0

S
Description
This repository is a mirror of https://git.openwrt.org/openwrt/openwrt.git It is for reference only and is not active for check-ins. We will continue to accept Pull Requests here. They will be merged via staging trees then into openwrt.git.
Readme BSD-2-Clause BSD-3-Clause GPL-1 GPL-2 ISC Linux-syscall-note MIT
1.2 GiB
0 Stars 1 Watchers 0 Forks
Languages
C 60.6%
Makefile 23.1%
Shell 8.1%
Perl 2.6%
UnrealScript 2.4%
Other 3%