On the Pi 4B, what is the correct way to persistently force the eth0 interface to 100 mbps Full Duplex? Thanks.
4 Answers
You should have a utility named ethtool
on your system. I presume you're acquainted with it. If not, please review man ethtool
. Before making any settings persistent, you should first verify that the settings won't cause you to be locked out of your system. If you break something with ethtool
before you make it persistent, you can recover by power cycling your RPi. If you make an erroneous change persistent, recovery may become more difficult - possibly requiring you to re-flash your SD card.
Also N.B. that forcing eth0
on your RPi to adopt fixed parameters may require the other side of the connection (e.g. switch, router, etc) be modified also. I am not sure that forcing your adapter to 100 Mbps & full duplex is the best way to achieve your objective. Consequently, this answer proposes a different approach using the advertise
option in ethtool
to set eth0
to always operate at 100-FD:
The approach: advertise
only 100baseT Full
I suppose this could be considered inflexible negotiation, as you are instructing eth0
to negotiate, but accept only 100baseT Full
from the connected device. Before changing any settings, use ethtool
to review the current settings for eth0
and its "Link Partner" - the upstream device (router, switch, etc):
Verify eth0
and Link partner
share the desired settings
$ ethtool eth0
...
$
In the output, review the settings for Advertised Link Modes
for eth0
, and for its Link Partner
; for example:
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Note that in this case, 100baseT/Full
is common to eth0
and its Link partner
. Once you've verified this common ground, make the following change:
Use ethtool
to change eth0
advertisement
$ sudo ethtool -s eth0 advertise 0x008
$
It may take a few seconds for RPi to "digest" this change. Assuming it completes without error, verify the change was accepted:
$ ethtool eth0
...
$
The Advertised link modes
should now show only the desired option:
Advertised link modes: 100baseT/Full
Networking can be verified, and should be fully functional at this point - you may or may not notice a speed difference. If something has "gone wrong", and you find connectivity lost or impaired, reboot
, or power-cycle the RPi to restore the defult configuration. Changes made with ethtool
at the CLI are not persistent across reboots. If you're satisfied, you can make the change persistent by modifying /etc/network/if-pre-up.d/ethtool
:
Modify /etc/network/if-pre-up.d/ethtool
for persistent changes
/etc/network/if-pre-up.d/ethtool
is a shell script run before the interface is brought up. A "default" script is provided - you will need to modify it to make any ethtool
configuration changes persistent across reboot
s.
What follows is admittedly a hack. That is to say I'm sure the code can be made more elegant, but I have tried this on my RPi 4, and it does work:
$ sudo nano /etc/network/if-pre-up.d/ethtool
Use the editor to add the following line to the end of the script:
$ETHTOOL --change eth0 advertise 0x008
Following is the result used on my RPi 4 test system:
#!/bin/sh
ETHTOOL=/sbin/ethtool
test -x $ETHTOOL || exit 0
[ "$IFACE" != "lo" ] || exit 0
# Gather together the mixed bag of settings applied with -s/--change
SETTINGS="\
${IF_ETHERNET_PORT:+ port $IF_ETHERNET_PORT}\
${IF_DRIVER_MESSAGE_LEVEL:+ msglvl $IF_DRIVER_MESSAGE_LEVEL}\
"
[ -z "$SETTINGS" ] || $ETHTOOL --change "$IFACE" $SETTINGS
$ETHTOOL --change eth0 advertise 0x008
-
possibly requiring you to re-flash your SD card
- or in the case of networking not working, simply attach a keyboard and monitor :p Sep 5, 2020 at 0:25 -
@JaromandaX: That would be a neat trick with the "Lite" version of RPi OS.– SeamusSep 5, 2020 at 1:07
-
the lite version of RPi OS handles screen and keyboard perfectly well - I fail to see your point - lite just means no GUI - the CLI is perfectly functional over keyboard and monitor Sep 5, 2020 at 1:08
-
@JaromandaX: I did not know that - thanks for the enlightenment. But it does require "stuff" (keyboard, monitor, cable) that may not be on hand... thus the word, "possibly".– SeamusSep 5, 2020 at 1:16
-
true - but you'd probably have keyboard and monitor on the PC you flashed the SD card on (OK, laptops are way more popular these days than 10 years ago, but still ...) Sep 5, 2020 at 1:55
I know this is an old topic, but I wanted to share an alternate solution in case anyone else runs into this problem.
The ethtool advertise approach described by Seamus works, but finding usable hooks to configure the interface at boot time and whenever the interface gets reset is not easy. Not to mention that the configuration inevitably happens after the interface has been started. I ended up writing a custom systemd service, but it definitely felt like a hack.
Eventually, I found a much simpler solution using a custom device tree overlay. The overlay configures the max-speed of the phy at boot time. This effectively disables gigabit on the interface. I am using this on a custom CM4 carrier board and it works perfectly every time.
Here is the device tree overlay source: cm4-disable-gigabit-ethernet.dts:
/dts-v1/;
/plugin/;
/ {
/* Change the phy max-speed to 100 Mbps */
fragment@0 {
target = <&phy1>;
__overlay__ {
max-speed = <100>;
};
};
};
The overlay is compiled and installed as follows. Then add "dtoverlay=cm4-disable-gigabit-ethernet" to /boot/config.txt
dtc -@ -Hepapr -I dts -O dtb -o cm4-disable-gigabit-ethernet.dtbo cm4-disable-gigabit-ethernet.dts
sudo cp cm4-disable-gigabit-ethernet.dtbo /boot/overlays/
-
Thanks for posting. The ethtool solution worked, but I'll keep this alternative in mind if facing the situation again.– MAXdBAug 10 at 14:09
There is a setting to force 100Mbps.
The commands are (although you may need to use in a different order):-
sudo ethtool -s eth0 autoneg off
sudo ethtool -s eth0 speed 100
You should check man ethtool
You could simply just connect the devices with a cat 5 Ethernet cable which has a maximum throughput of 100mbps.
eth0
settings usingethtool
?