Wednesday, May 30, 2018

Fixing Unstable WiFi in Latest Ubuntu/Arch Linux

My laptop is Thinkpad Yoga S3 (2015). I happened to run into an issue where intermittently my Internet connection (via WiFi) wouldn't work, although my other devices worked just fine. When this happened, I re-connected my WiFi and the Internet worked again! Initially I thought this was because of my Ubuntu 16.04 wasn't stable. But after upgrading to 18.04, the problem still persisted! I have finally figured it out and fixed it though :)


1. ThinkPad Yoga S3 has Intel 7265D card, apparently the latest firmware is buggy. So if you run into the same issue, check if your WiFi card the same version

$ sudo lshw -C network

You'll see something like this:
  *-network                
       description: Wireless interface
       product: Wireless 7265
       vendor: Intel Corporation
       physical id: 0
       bus info: pci@0000:02:00.0
       logical name: wlp2s0
       version: 59
       serial: 60:57:18:ad:54:3f
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress bus_master cap_list ethernet physical wireless
       configuration: broadcast=yes driver=iwlwifi driverversion=4.16.10-1-ARCH firmware=22.391740.0 ip=192.168.100.4 latency=0 link=yes multicast=yes wireless=IEEE 802.11
       resources: irq:46 memory:d4100000-d4101fff

2. Check what version of driver is currently running
```
$ dmesg | grep iwlwifi

You'll see something like this:

Dec 20 23:00:08 drax kernel: iwlwifi 0000:03:00.0: Microcode SW error detected.  Restarting 0x2000000.
Dec 20 23:00:08 drax kernel: iwlwifi 0000:03:00.0: Loaded firmware version: 27.168.6.1
```

3. The issue is apparently that the newest firmware is buggy. In my case, version 29 and 27 are both buggy. This explains why back when I was using 14.04, things were nice and stable.

4. To fix it, we have to downgrade the firmware. It's really easy. There is a directory where all different firmware versions for the WiFi card is located. On boot, the system loads the latest version. So to downgrade, we just have to remove the latest version so the system would pick the previous one

```
Check firmwares version that are available:
$ ls /usr/lib/firmware/iwlwifi-7265D-*.ucode

In my case:
lrwxrwxrwx 1 root root      21 May  9 00:27 /usr/lib/firmware/iwlwifi-7265D-10.ucode -> iwlwifi-7265-10.ucode
-rw-r--r-- 1 root root 1002800 May  9 00:27 /usr/lib/firmware/iwlwifi-7265D-12.ucode
-rw-r--r-- 1 root root 1008692 May  9 00:27 /usr/lib/firmware/iwlwifi-7265D-13.ucode
-rw-r--r-- 1 root root 1384500 May  9 00:27 /usr/lib/firmware/iwlwifi-7265D-16.ucode
-rw-r--r-- 1 root root 1383604 May  9 00:27 /usr/lib/firmware/iwlwifi-7265D-17.ucode
-rw-r--r-- 1 root root 1385368 May  9 00:27 /usr/lib/firmware/iwlwifi-7265D-21.ucode
-rw-r--r-- 1 root root 1028376 May  9 00:27 /usr/lib/firmware/iwlwifi-7265D-27.ucode
-rw-r--r-- 1 root root 1028376 May  9 00:27 /usr/lib/firmware/iwlwifi-7265D-29.ucode
In my case, versions 29 and 27 are buggy. So I moved it away
$ sudo mv  /usr/lib/firmware/iwlwifi-7265D-27.ucode ~/tmp
$ sudo mv  /usr/lib/firmware/iwlwifi-7265D-29.ucode ~/tmp
```

5. Restart, the system. Things are working fine now :)