ThinkPad T450s ethernet and suspend

ThinkPad T450s ethernet and suspend

May 12, 2020

There seems to be a problem in Linux with the Intel E1000 ethernet device on a ThinkPad T450s, and possibly other machines that use the e1000e device driver. The symptom is that Network Manager (NM) hangs trying to initialize the ethernet link after a suspend/resume cycle. After a resume, NM shows a spinning icon for about 10 seconds trying to get an IP address, and it eventually gives up. Telling NM to try again results in the same failure, forcing you to unplug and replug the network cable.

The problem described below is still present in Linux Mint 22 and Fedora 42. From this I conclude that it is not likely to be fixed in the future, so the following workaround will always be necessary.

I observed this problem with every Linux Mint version from 19.1 up, and on Fedora 42. It seems that the e1000e network device driver fails to establish a link after a suspend / resume cycle.

The solution is to do the following before a suspend:

  1. Disable NetworkManager
  2. Bring down the ethernet link.
  3. Unload the e1000e kernel module.

It’s very important to unload the e1000e module after all the other steps; otherwise it will have a non-zero reference count and the kernel will refuse to unload it.

On resume, undo those steps in reverse order:

  1. Load the e1000e kernel module.
  2. Bring up the ethernet link.
  3. Enable NetworkManager.

After some searching, I came across a fix (link is broken now 1) that uses systemd to disable the ethernet device before suspend, and enable it after resume. Unfortunately, there are some typos in the proposed systemd scripts: a superfluous ‘[’ character, and missing spaces surrounding semicolons in the command lines.

Below is the modified fix for the problem. Log in as root to perform all of these steps, or prefix each command with sudo.

Create the file /etc/systemd/system/network-suspend.service with the following contents:

#/etc/systemd/system/network-suspend.service
#sudo systemctl enable network-suspend.service
[Unit]
Description=Stop network components prior to suspending
Before=sleep.target

[Service]
Type=oneshot
ExecStart=/bin/systemctl stop NetworkManager.service ; /bin/ip link set enp0s25 down ; /sbin/modprobe -r e1000e

[Install]
WantedBy=sleep.target

If you are using a different ethernet device, use the ifconfig command to determine the device name for ip link, and the lspci -v command to determine the driver name for modprobe.

Similarly, create the file /etc/systemd/system/network-resume.service with the following contents:

#/etc/systemd/system/network-resume.service
#sudo systemctl enable network-resume.service
[Unit]
Description=Start network components after resuming
After=suspend.target

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 1s
ExecStart=/sbin/modprobe e1000e ; /bin/sleep 1s ; /bin/ip link set enp0s25 up ; /bin/systemctl start NetworkManager.service

[Install]
WantedBy=suspend.target

Tell systemd to enable and then load the new service files using:

systemctl enable network-suspend.service
systemctl enable network-resume.service
systemctl daemon-reload

Before seeing if these new services work in a suspend/resume cycle, you can test them manually. First, try the suspend service:

systemctl start network-suspend.service
systemctl status network-suspend.service

The second command should show any errors that might have occurred.

Similarly, test the resume service using:

systemctl start network-resume.service
systemctl status network-resume.service

Now you can test a suspend/resume cycle. Note that after the resume, there is a two second delay before Network Manager reports that the ethernet device is connected. This is due to the two sleep commands in /etc/systemd/system/network-resume.service. It’s possible that these delays could be reduced further, but two seconds seems innocuous.


  1. This is why I always try to copy solutions into my own posts, as a hedge against Internet Rot. ↩︎