Categories
SysOps

How to reload wifi module on resume

Once in a while, I have a problem with Intel Corporation Dual Band Wireless-AC 7265 on Dell XPS 13 during the resume process as it just stops working and won’t connect to any network. The solution is to simply reload the kernel module.

Simple ad hoc solution

The simplest ad hoc solution is to execute the following shell script as root using sudo utility. It will look for interface is not ready message inside the kernel ring buffer and verify that interface is not connected to any network before reloading the module.

#!/bin/sh
# reset Intel Corporation Dual Band Wireless-AC 7265 on Dell XPS 13

# network interface name
interface="wlp2s0"

# syslog tag
tag="wifi-resume"

# check for "interface: link is not ready"
(dmesg | tail -10 | grep "${interface}: link is not ready")>/dev/null

if [ "$?" -eq 0 ]; then
    logger -t $tag "$interface is not ready"
    if [ -z "$(iwgetid --raw $interface)" ]; then
        logger -t $tag "$interface is not connected to any network"
        modprobe -r iwlwifi
        modprobe iwlwifi
    fi
    
fi

Automated solution

Create /etc/pm/sleep.d/75_wifi-resume shell script to perform the reload operation on the resume. This is mainly the old way, but I will incorporate it with systemd.

$ cat <<EOF | sudo tee /lib/systemd/system-sleep/wifi-resume
#!/bin/sh
set -e

if [ "\$2" = "suspend" ] || [ "\$2" = "hybrid-sleep" ]; then
    case "\$1" in
        pre)
            # do nothing
            :
            ;;
        post)
            /etc/pm/sleep.d/75_wifi-resume resume
            ;;
    esac
fi
EOF	 

Ensure that the proper owner and permissions are set.

$ sudo chown root:root /etc/pm/sleep.d/75_wifi-resume
$ sudo chmod 755 /etc/pm/sleep.d/75_wifi-resume

Create /lib/systemd/system-sleep/wifi-resume shell script that will be automatically executed by systemd.

$ cat <<EOF | sudo tee /lib/systemd/system-sleep/wifi-resume
#!/bin/sh
set -e
if [ "$2" = "suspend" ] || [ "$2" = "hybrid-sleep" ]; then
    case "$1" in
        pre)
            # do nothing
            :
            ;;
        post)
            /etc/pm/sleep.d/75_wifi-resume resume
            ;;
    esac
fi
EOF

Ensure that the proper owner and permissions are set.

$ sudo chown root:root /lib/systemd/system-sleep/wifi-resume
$ sudo chmod 755 /lib/systemd/system-sleep/wifi-resume