Surface Pro 1796 Wifi not resuming after suspend

U did not have that much time to work on it as i did. Anyhow, the final hint came from you. And as a side effect I learned a lot of my new system and now i love it even more. Now I am trying to dig into the “no battery found” problem.

Thank you for all your efforts in this matter :smile:

Oh, pls post the solution u were working on. I would like to test it.

I haven’t tested it yet. No point in posting it unless it works. If it does I will post. Good work on your part.

Mark your script as the solution to close the thread out. I’m very glad it worked. Your welcome, and glad I could help get this resolved

Part 1) WiFi module suspend scripts:

Create a simple script to unload your network WiFi module before entering suspend. Substitute in your Wifi module where appropriate.

#!/bin/bash
modprobe -r 8812au

Save as /usr/bin/netmod-suspend.sh & make it executable and owned by root:

sudo chown root:root /usr/bin/netmod-suspend.sh
sudo chmod +x /usr/bin/netmod-suspend.sh

Create a systemd unit file with the following contents:

# cat netmod-suspend.service 
# /etc/systemd/system/netmod-suspend.service
[Unit]
Description=Network module suspend helper
Before=sleep.target

[Service]
Type=simple
ExecStart=-/usr/bin/netmod-suspend.sh

[Install]
WantedBy=sleep.target

Save it as /etc/systemd/system/netmod-suspend.service & make it executable and owned by root

sudo chown root:root /etc/systemd/system/netmod-suspend.service
sudo chmod +x /etc/systemd/system/netmod-suspend.service

Then:

sudo systemctl enable netmod-suspend.service
sudo systemctl start netmod-suspend.service

This sucessfully unloaded the wifi module before suspend. I did not write the other systemd unit file to automatically load the wifi module after resume. No point as your solution was working fine. I simply ran:

sudo modprobe 8812au

(Edit) - Part 2 (below) contains the scripts to load your WiFi modules after resuming from suspend.

Part 2) WiFi module resume scripts:

Create a simple script to load your network WiFi module after resuming from suspend. Substitute in your Wifi module where appropriate.

#!/bin/bash
modprobe 8812au

Save as /usr/bin/netmod-resume.sh & make it executable and owned by root.

sudo chown root:root /usr/bin/netmod-resume.sh
sudo chmod +x /usr/bin/netmod-resume.sh

Create a systemd unit file with the following contents:

# systemctl cat netmod-resume.service
# /etc/systemd/system/netmod-resume.service

[Unit]
Description=Network module resume helper
After=suspend.target

[Service]
Type=simple
ExecStart=-/usr/bin/netmod-resume.sh

[Install]
WantedBy=suspend.target

Save it as /etc/systemd/system/netmod-resume.service & make it executable and owned by root.

sudo chown root:root /etc/systemd/system/netmod-resume.service
sudo chmod +x /etc/systemd/system/netmod-resume.service

Then:

sudo systemctl enable netmod-resume.service
sudo systemctl start netmod-resume.service

Part 1 + Part 2 are complete working suspend and resume WiFi service scripts. The scripts may be modified to suspend /resume bluetooth modules as well (or instead of wifi).

COOL! I will check this out. Meanwhile after some more testing (basically unloading and loading the modules too fast) the network got messed up somehow. So I had to change the script and I think it’s not a good idea to unload an load this stuff in a loop and completely uncontrolled manner in the first place. Here is the final script. Dunno if this is the right way to do such things but now it runs stable.

[suchus@PSYCHO ~]$ cat /usr/lib/systemd/system-sleep/unload-load_modules.sh
#!/bin/sh
# unload/load wifi kernel module sleep/resume
# systemd will call this script with the arg "pre" before suspend and
# the arg "post" before resume. There is a second arg which is not
# relevant here for my system. This arg is accessable in $2 and contains things like sleep, resume, hibernate...
# replace the next line with your wifi module "mod=<your module>"
mod=mwifiex_pcie
case $1 in
    pre)
        echo "Shutting down wifi & network..."
	/usr/bin/nmcli radio wifi off
	/usr/bin/nmcli network off
	echo "Removing module $mod..."
	/usr/bin/modprobe -v -r $mod
        ;;
    post)
	echo "Loading module $mod..."
	/usr/bin/modprobe -v $mod
        echo "Starting up wifi & network..."
	/usr/bin/nmcli network on
	/usr/bin/nmcli radio wifi on
	;;
esac

I also think it is important to notice that modprobe automatically removes and loads dependent modules.

[suchus@PSYCHO ~]$ sudo /usr/lib/systemd/system-sleep/unload-load_modules.sh pre
Shutting down wifi & network...
Removing module mwifiex_pcie...
rmmod mwifiex_pcie
rmmod mwifiex
rmmod cfg80211
[suchus@PSYCHO ~]$ sudo /usr/lib/systemd/system-sleep/unload-load_modules.sh post
Loading module mwifiex_pcie...
insmod /lib/modules/4.17.0-1-MANJARO/kernel/net/wireless/cfg80211.ko.xz 
insmod /lib/modules/4.17.0-1-MANJARO/kernel/drivers/net/wireless/marvell/mwifiex/mwifiex.ko.xz 
insmod /lib/modules/4.17.0-1-MANJARO/kernel/drivers/net/wireless/marvell/mwifiex/mwifiex_pcie.ko.xz 
Starting up wifi & network...

For my metal (Surface Pro 1796) this is the final solution. You might want to check on the systemd service below this posting and modify it. I don’t want to dig to deep into it. This solution here and after studying systemd for a short time seems to me the straight forward thing to do and is specifically allowed to do. Teach me different :slight_smile:

1 Like

I am no scripting wizard. I am just a duffer who finds solutions from pure obstinacy. I consider it an affront if my computer ever gets the better of me. My strong suit is just never knowing when to say “give”. I usually just beat my computer into submission with my bull headed refusal to quit.

1 Like

I can sign that :smile:

Part 2) WiFi module resume scripts:

Create a simple script to load your network WiFi module after resuming from suspend. Substitute in your Wifi module where appropriate.

#!/bin/bash
modprobe 8812au

Save as /usr/bin/netmod-resume.sh & make it executable and owned by root.

sudo chown root:root /usr/bin/netmod-resume.sh
sudo chmod +x /usr/bin/netmod-resume.sh

Create a systemd unit file with the following contents:

# systemctl cat netmod-resume.service
# /etc/systemd/system/netmod-resume.service

[Unit]
Description=Network module resume helper
After=suspend.target

[Service]
Type=simple
ExecStart=-/usr/bin/netmod-resume.sh

[Install]
WantedBy=suspend.target

Save it as /etc/systemd/system/netmod-resume.service & make it executable and owned by root.

sudo chown root:root /etc/systemd/system/netmod-resume.service
sudo chmod +x /etc/systemd/system/netmod-resume.service

Then:

sudo systemctl enable netmod-resume.service
sudo systemctl start netmod-resume.service

Part 1 + Part 2 are complete working suspend and resume WiFi service scripts.

Cheers

1 Like

It works really smooth. I think it’s more elegant and system conform than my solution. After testing it I put it all in one script which i found on the ubuntu link mentioned earlier in this thread. I never would have dared to touch this systemd service, target, unit stuff

[suchus@PSYCHO ~]$ cat /etc/systemd/system/netmod-suspend.service 
[Unit]
Description=Network module suspend helper
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=-/sbin/modprobe -v -r mwifiex_pcie
ExecStop=-/sbin/modprobe -v mwifiex_pcie

[Install]
WantedBy=sleep.target

this way we do not have to take care about the NetworkManager. This service runs just before sleep and after the network is aready cleanly shutdown.
Way cool sh*t :smile:

1 Like

Yes it is cool. I am not fond of writing systemd units, and rarely ever do. The way things work now that is sometimes the only way to accomplish what you want. Glad you are happy with the result, and it only took 50+ posts :smile:

BTW you should change the solution to your last post if that is the method that you like the best.

Hi,
I had to change the solution again. The new service works fine but after excessive testing (opening/closing lid, issuing 'sudo systemctl suspend in a matter of seconds) this will fail every once in a while. Not so with the script in /usr/lib/systemd/system-sleep. This runs rock solid.

1 Like

As I stated earlier am far from a pro at scripting or writing systemd unit files. I do think you could get the systemd method working better for you though. I’m guessing the problem is that the module is being loaded too quickly, while the computer is still in the resume process. A simple “sleep 10” command before the module is reloaded may be all that is needed to fix your issue.

The problem on my side is, i don’t know much about systemd. What i know is, that everything is halted until this (or all the scripts in this directory) is finished. This way we know what’s happening there. Otherwise systemd wants to run everything at the same time (creating, deleting, writing, reading sockets/fifos and more). At boot time this works really good. But in my case it is like telling systemd “Hey, i will bring my faulty device to a safe place before you can screw up on it”. What the impact is on the rest of the services? Heck, I don’t know. All I know for now is that it works.

1 Like

Hey! Awesome work. I am just in the throws of trying to get this to work on my Surface Pro 2017. So, what is the final solution?

Also, can you describe how you have your power settings configured. Screen blanking/locking/suspend to RAM/suspend to disk/lid close? Where do you configure ll that stuff?

Thanks for your good work on this!

You should really open a separate support thread for each issue you need help with. Be sure to post your full hardware specs in your initial post.

Information on how to post hardware specs and logs on the forum:

here are some links that will be of help with your suspend issue:

I have many other posts on this topic if you search the forum.

https://forum.manjaro.org/t/kernel-4-19-0-3-not-network-after-suspending-gnome-edition/63544/2

https://forum.manjaro.org/t/wifi-adapter-tp-link-tl-wn823n-must-be-reconnected-for-it-to-work/52968/19

https://forum.manjaro.org/t/surface-pro-1796-wifi-not-resuming-after-suspend/48133/47

https://forum.manjaro.org/t/thinkpad-x230t-wont-suspend-under-kernel-419rc4-4-18-4-17-4-14-4-9/59798/21

Here are some external links with excellent systemd reference material:

The ArchWiki - systemd

Red Hat - systemd-targets

Red Hat - systemd unit files

Systemd manpage

It is mainly the work of @tbg. I would not have been able to fix it w/o him and his professional advise. Teamwork!

1 Like

A simple “sleep 10” command before the module is reloaded may be all that is needed to fix your issue.

Do you mean this:
ExecStopPre=sleep 10

No that is not right. You must post the whole example for me to see if it is correct.

Here is an example from the first post I linked:

[[Unit]
Description=Start network components after resuming
After=suspend.target

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 15s
ExecStart=/bin/modprobe r8169; ip link set enp2s0 up; systemctl start NetworkManager.service

[Install]
WantedBy=suspend.target

Or, alternately:

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/sleep 15
ExecStart=/usr/bin/modprobe r8169
ExecStart=/usr/bin/sleep 3
ExecStart=/usr/bin/ip link set enp2s0 up
ExecStart=/usr/bin/sleep 3
ExecStart=/usr/bin/systemctl start NetworkManager