WiFi

From postmarketOS

General information

To get wireless LAN working, most WiFi chips need a proprietary firmware blob. While it would be more secure to replace that with open source software in the long term, it isn't feasible right now, so we try to get it working with that closed source firmware.
A great place to start looking for information about many available WiFi chips is this kernel.org page. It often provides driver sources and the required firmware blobs as well. For a start if you want Internet working try the USB Internet guide.

Note Instead of mounting Android's firmware partition, we package the files ourselves (see the FAQ).

Useful links:

Qualcomm WiFi

Devices with Qualcomm WiFi chips are usually very easy to get working.

You need to find the firmware files for your device, the main file is called wcnss.mdt and there should also be more files which are called wcnss.b00, wcnss.b01, etc. Copy them all onto your device into /lib/firmware/postmarketos. There may also be files starting with WCNSS, e.g. WCNSS_cfg.dat WCNSS_qcom_cfg.ini WCNSS_qcom_wlan_nv.bin - those should go into some path like /lib/firmware/postmarketos/wlan/prima or /lib/firmware/postmarketos/wlan/qca_cld depending on the device. You can use existing firmware packages as examples for which files go where, e.g. aports/firmware/firmware-xiaomi-armani.

Take Samsung phones for example. WCNSS_qcom_wlan_nv.bin can be located as /etc/firmware/wlan/prima/WCNSS_qcom_wlan_nv.bin in Android system partition.

Then you can run as root (sudo -i first) echo 1 > /dev/wcnss_wlan and echo sta > /sys/module/wlan/parameters/fwpath. Check the output of ip link and a wlan0 interface should have appeared! Now you can use NetworkManager to connect to a WiFi network!

If that didn't work, please check the debugging section how to find out what went wrong.

For packaging, see that page and add the wcnss-wlan package (which runs the two commands above at boot automatically) as a dependency to the WiFi subpackage.

Test your packaging by flashing a new rootfs which includes your changes and see if WiFi works without any manual configuration.

Broadcom WiFi

Icon TODO: This section needs expansion.

Devices with Broadcom WiFi chips usually have the path to the firmware hardcoded in the kernel, mostly to /system/vendor/firmware.

In most cases you should be able to set CONFIG_BCMDHD_FW_PATH and CONFIG_BCMDHD_NVRAM_PATH in the kernel config. In other cases, you need to patch the kernel and change the path to /lib/firmware/postmarketos (see this patch).

You can use the command git grep "lib/firmware/postmarketos" device/linux-* in pmaports to find how it's done for other devices.

An example of how Broadcom was made to work can be found at Samsung_Galaxy_S_Advance_(samsung-i9070)#How_drebrez_made_wifi_work and in the corresponding merge request. Another example is Medion_Lifetab_S9714_(medion-kai)#How_bonsaiblue_made_wifi_work.

Here's a quick rundown of the steps required to get Broadcom WiFi up and running:

  • Locate the nvram and firmware files. You might be able to use the ones from firmware-aosp-broadcom-wlan, but if they don't work you can package your own.
  • Modify your kernel config to point to the new firmware paths.
  • Modify your kernel APKBUILD to build modules, so that you can use bcmdhd.
  • Add a modules-load.conf file to your device package and put the bcmdhd module name (usually dhd) in it, then modify the APKBUILD to install the file. (This will auto-load the dhd module on startup.)

See the Galaxy S Advance device package, Galaxy S Advance linux package and Galaxy S Advance firmware package for reference.

Mediatek WiFi

Icon TODO: Improve this section to include a general explanation for all MTK SoCs
Note There is at least one MediaTek device in pmaports with WiFi working. Vernee Thor Wifi Guide

Introduction, software

Devices with Mediatek WiFi chips are much more complicated to get working. The best way to know how your specific SoC works is to look at the init.rc scripts from an Android ROM available for your phone and look for the chip initialization (search for "/dev/stp", "mtk_stp" and "wmt").

Usually, you may notice wmt_loader and 6620_loader programs doing some work to initialize the wireless communication hardware. The tool called 6620_launcher which (probably) loads the firmware from the filesystem into the kernel. Depending on device, 6620_launcher can use different protocols for communicating with chip. This tool is a binary included in the Android installation and linked against the bionic libc, and could not be run on postmarketOS because it uses linking against musl. There are several solutions to this problem:

The MediaDeb project has made systemd unit files running more or less the commands above on two of their supported devices:

  • wifi_loader.service: runs mt6620_loader.sh (which does mknod) & runs wifi_loader bin
  • mt6620_launcher.service: runs 6620_launcher (/usr/sbin/6620_launcher -b 4000000 -p /lib/firmware/ -d /dev/ttyMT2)
  • wifi.service: runs echo 1 > /dev/wmtWifi

MT6589

On the Fairphone 1, the order for initialization should be the following (based on the init.rc files from Android):

# Install the files mt6628_ant_m1.cfg mt6628_patch_e1_hdr.bin mt6628_patch_e2_0_hdr.bin mt6628_patch_e2_1_hdr.bin WIFI_RAM_CODE_MT6628 WMT.cfg into /system/etc/firmware/ (path could be patched in the kernel sources)
insmod mtk_hif_sdio.ko
insmod mtk_stp_wmt.ko
insmod mtk_stp_uart.ko
insmod mtk_stp_gps.ko
insmod mtk_stp_bt.ko
insmod mtk_wmt_wifi.ko

mknod /dev/stpwmt c 190 0
mknod /dev/stpgps c 191 0
mknod /dev/stpbt  c 192 0
mknod /dev/wmtWifi c 153 0

insmod wlan_mt6628.ko

6620_launcher -p /system/etc/firmware/

echo 1 > /dev/wmtWifi

MT6577 (MT8317) with MT6628 combochip

This section describes how arzamas-16 made Wi-Fi work on Acer Iconia B1-A71 (not yet in pmaports) which has mt8317 (tablet revision of mt6577) SoC and mt6628 combochip on downstream kernel (v3.4.113). The combochip on my device uses UART to communicate with operating system. Please keep in mind this section is meant to describe a set of «hacks» I went thru rather than being a complete guide. Also YMMV but at the time of writing scanning for networks, and connecting†, and accessing the internet work.

Following my steps will not make wifi work on mt67xx as these SoCs are more modern than the ancient stuff I have, and they use more tools which may be incompatible with those I describe below. I recommend checking out Dahrkael's and MediaDeb projects (see above).

† there are 2 methods you can get working Wi-Fi right now: using the downstream executables and their dependencies or using the modern software offered by postmarketOS.

Method Pros Cons
Using downstream executables Less time demanding. Could only be configured through console. Incompatible with networkmanager. Effectively crashes wpa_supplicant and networkmanager services. Requires running many outdated proprietary executables. Needs a lot of space to store these binaries. Less flexible configuring.
Modern approach Compatible with postmarketOS services. Configurable via GUI (tested in XFCE4). Uses more fresh open source software. Less dependent on precompiled binaries. Takes a lot of time in case when your device is specific or very old.

Sorting out possible issues with downstream kernels

1. Ensure that kernel modules are compiled and packaged into your pmOS installation! In my linux-.../APKBUILD I package them the following way:

package() {
	downstreamkernel_package "$builddir" "$pkgdir" "$_carch" "$_flavor" "$_outdir"
	# Modules
	unset LDFLAGS
	make O="$_outdir" ARCH="$_carch" CC="${CC:-gcc}" \
		KBUILD_BUILD_VERSION="$((pkgrel + 1))-postmarketOS" \
		INSTALL_MOD_PATH="$pkgdir" \
		modules_install

}

In my case, they have been installed to /lib/modules/3.4.113/kernel/mediatek/kernel/drivers/combo

2. For some downstream mediatek kernels gcc6 complains about gl_kal.h, if you will get such errors apply this simple kernel patch!

3. In order to be able to connect to password-protected networks, be sure to have this kernel patch applied!

4. All downstream kernels I've worked with have many hardcoded paths specific to Android. As stated at the top of this page, postmarketOS packages firmware blobs so they will definitely be in the other path. You can either:

  • Manually replace hardcoded paths once in the source code
  • Make firmware paths customizable with kernel config options so you could change many paths with a single kconfig change. See my commits which do it with wifi and nvram paths. In my kernel config for postmarketOS I've set:
CONFIG_MTK_WMT_FW_PATH="/lib/firmware/postmarketos/"
CONFIG_MTK_NVRAM_PATH="/lib/firmware/postmarketos/"

Dumping firmware from Android

This step should be done prior to flashing postmarketOS. If you plan to bring up wifi using downstream executables then also check the steps in corresponding section prior to flashing postmarketOS. Dump the following:

  • Contents of /system/etc/firmware/ (there should be ~10 files)
  • /data/nvram directory

After flashing postmarketOS, copy the dumped files to /lib/firmware/postmarketos so the structure will look like

giordano:~$ ll /lib/firmware/postmarketos/
total 3.9M
drwxr-xr-x 3 root 4.0K Aug 24 21:57 .
drwxr-xr-x 3 root 4.0K Jan  1  2012 ..
drwxr-xr-x 5 root 4.0K Aug 24 21:57 nvram/
-rw-r--r-- 1 root 682K Aug 24 21:53 DSP_ROM
(some stuff)
-rw-r--r-- 1 root  28K Aug 24 21:53 mt6628_patch_e1_hdr.bin
-rw-r--r-- 1 root  25K Aug 24 21:53 mt6628_patch_e2_hdr.bin

Loading modules

First of all, it's important to understand how Wi-Fi initialization happens on your device when running Android. For this, you will need to acquire .rc scripts from the ramdisk. Look for init.rc and whatever it invokes. In my case I had 2 files: init.rc and init.project.rc. Here is the part related to wifi from init.rc (omitting unnecessary stuff like numerous chmod's and chown's):

Note Notice that .rc files mention mt6620 while in fact the combochip in my device is mt6628. Check where the /system/lib/modules/wlan.ko links to!
#
# MT6620 related device nodes & configuration (begin)
#

# STP, WMT, GPS, FM and BT Driver
    insmod /system/lib/modules/mtk_hif_sdio.ko
    insmod /system/lib/modules/mtk_stp_wmt.ko
    insmod /system/lib/modules/mtk_stp_uart.ko
    insmod /system/lib/modules/mtk_stp_gps.ko
    insmod /system/lib/modules/mtk_stp_bt.ko
    insmod /system/lib/modules/mtk_wmt_wifi.ko

# Create char device file for WMT, GPS, BT, FM, WIFI
    mknod /dev/stpwmt c 190 0;
    mknod /dev/stpgps c 191 0;
    mknod /dev/stpbt  c 192 0;
    mknod /dev/wmtWifi c 153 0

# Load WiFi Driver
    insmod /system/lib/modules/wlan.ko (COMMENT: this is a symlink to wlan_mt6628.ko)

#
# MT6620 related device nodes & configuration (end)
#

The next step is to load said modules and I wrote a simple script for doing this on my device: Github Gist, invokation: sudo ./01-load-wifi-modules.sh. At this point we've replicated the work done in init.rc on Android regarding wifi.

Note The modules should be loaded at every boot

Programs overview

Here is the part related to wifi from init.project.rc (omitting unnecessary parts like detailed service parameters):

service 6620_launcher /system/bin/6620_launcher -m 1 -b 4000000 -p /system/etc/firmware/ -d /dev/ttyMT2 (config omitted...)
service stp_dump /system/bin/stp_dump3 (config omitted...)
service hald /system/bin/hald (config omitted...)   
service p2p_supplicant (config omitted...)
service wpa_supplicant /system/bin/logwrapper /system/bin/wpa_supplicant \
	-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -e/data/misc/wifi/entropy.bin -ddd
	(config omitted...)
service ap_daemon (config omitted...)

Now it's necessary to sort out which programs (services) are required to start wifi. Below is a very short description of programs mentioned in my init.project.rc file.

  • 6620_launcherrequired establishes a connection with a combochip, does some simple initialization and uploads a firmware blob.
  • stp_dump3 is used for debugging. Comments in the code say this program can break/disrupt wpa_supplicant.
  • haldrequired. On Android it loads and unloads kernel modules and manages combochip power. In fact, on postmarketOS this whole program could be replaced with one (worst case: two) shell command (more on that below).
  • p2p_supplicant manages features such as Wi-Fi Direct. I don't need it in my case.
  • wpa_supplicantrequired manages wifi connection. A vital part of wireless networking.
  • ap_daemon allows to create a wireless access point. I don't need it in my case.

As we can see, only 6620_launcher, and hald, and wpa_supplicant are required to start wifi.

(1) Bringing up wifi using downstream executables

Icon WARNING: This method is frowned upon in postmarketOS community. We encourage you to use as much open source software as possible. Proceed on your own!

In this part I will lack some details but you'll be able to easily figure out what to do.

Note Note to save /misc/wifi/wpa_supplicant.conf from Android to prevent unnecessary headache. Better if it already has your network saved.

1. From the running Android, dump:

  • /system/bin/linker, do not forget it as this thing is very important
  • /system/bin/6620_launcher
  • /system/bin/wpa_supplicant
  • The whole /system/lib directory

Recreate same structure in your postmarketOS installation: put dumped /system/... stuff in the root.

2. Stop and disable wpa_supplicant and networkmanager, I've made a stupid script for this:

#!/bin/sh

for s in "networkmanager" "wpa_supplicant"; do
	sudo rc-update del "$s" default
	sudo rc-service "$s" stop
	rc-service "$s" status
done

3. After you've loaded the kernel modules, start the 6620_loader using parameters from the .rc scripts from your device but change the path to firmware. As Vernee Thor wiki page states, this program needs to keep running, so better send it to background with &. Example:

/system/bin/6620_launcher -m 1 -b 4000000 -p /lib/firmware/postmarketos/ -d /dev/ttyMT2 &

Hit enter second time to return to console.

4. Power on the combochip:

echo -n '1' > /dev/wmtWifi

This takes few seconds to run and you will see some logs from 6620_launcher indicating uploading firmware into the combochip which has been turned on.

5. Launch wpa_supplicant parameters from the .rc scripts from your device. It's safe to omit entropy file and don't forget to supply the conf file. Depending on the wpa_supplicant implementation, you may or may not see the log output. You can also run this program in background using the &. Example:

/system/bin/wpa_supplicant -iwlan0 -Dnl80211 -c/home/user/my_wifi_network.conf -ddd

6. The last thing is to acquire an IP address from your access point! Use whatever program you want, I used dhcpcd

(2) Bringing up wifi using modern approach

Note Author of this section performed all these steps directly on live postmarketOS installation. You packaging experience with pmbootstrap may vary

1. The first and the hardest step is to find compatible 6620_launcher and build it.

The problem is Mediatek doesn't provide the source code of this tool as part of the kernel source code. Chances are extremely low but if your device vendor supplies 6620_launcher source code, you saved yourself tons of time. In my case I went straight to Github and began searching for the source code, usually there are various versions accidentally shared either by mediatek or device vendors.

Another huge problem is how Mediatek does versioning of 6620_launcher - all executables I've seen have "1.0-release" version code but their functionality varies to the greatest extent. For example, the MediaDeb Project's source code did not work on my device at all because it invokes IOCTL calls which are not supported by the old WMT driver at all. You will need to either rely on luck or carefully read through the source code.

You can use my Github search query but you'll need to sign into your account. At the time of writing, there are 66 repositories with 6620_launcher.

I also had to load my 6620_launcher from Android into Ghidra SRE on my PC to compare algorithms with sources on GH and to dump strings - some of them are unique to specific versions and it makes searching easier, for example my version doesn't have this string: "SOC chip no need do combo chip power on.\n".

After all of this, I've found working stp_uart_launcher in wedoinnov/HD5_lichee repo, omitting the firmware blobs. Most likely this tool will work on other old mt6575/mt6577/mt8317/mt8377 devices with mt6620/mt6628 combochips that work over UART.

2. After you've loaded the kernel modules, start the freshly compiled 6620_launcher using parameters from the .rc scripts from your device but change the path to firmware. As Vernee Thor wiki page states, this program needs to keep running, so better send it to background with &. Example:

/home/user/wifi/HD5_lichee/6620_launcher -m 1 -b 4000000 -p /lib/firmware/postmarketos/ -d /dev/ttyMT2 &

Hit enter second time to return to console.

3. Power on the combochip:

echo -n '1' > /dev/wmtWifi

This takes few seconds to run and you will see some logs from 6620_launcher indicating uploading firmware into the combochip which has been turned on.

4. Wait for a few seconds for the network interface to initialize and now you will be able to connect to wifi using network manager of your desktop environment. Enjoy the internet!

Note There's a bug when the password prompt doesn't appear upon connecting to secure network in XFCE4. Use nmtui to work it around.

HiSilicon WiFi

Note This section is in WIP state. Feel free to add more information.

Introduction, software

Devices with HiSilicon WiFi chips are comparatively easy to get working. If following instructions don't work for your device, you'll need to look at the *.rc scripts from an Android ROM available for your phone, as well as any other relevant for wifi scripts that they point to (search for hisi, hi110x, hi1101, hi1102, connectivity). In them you'll find `echo` (or `write` that can be translated to `echo`) commands that need to be run to initialize the wireless communication hardware.

The path to the firmware is usually hardcoded in the kernel and firmware files themselves to /vendor/firmware or /system/vendor/firmware, so if you want to change the path to /lib/firmware/postmarketos you'll need to patch the kernel and edit the *_cfg firmware files (see this patch).

An example of how HiSilicon was made to work can be found at https://wiki.postmarketos.org/wiki/User:Ignapk#How_ignapk_made_wifi_work and the corresponding merge request

For packaging, see that page and add the hisi-wlan package as a dependency to the WiFi subpackage.

Hi1101

On the Huawei P8 Lite, the order of the initialization should be the following (based on the *.rc files from Android 1 2):

# Install the firmware blobs into /system/vendor/firmware
echo 1 > /sys/devices/hi110x_ps/bfg_lowpower_enable
echo 12 > /sys/devices/hi110x_power/powerpin_state
echo 1 > /proc/wifi_enable/wifi_start
echo 1 > /proc/oam_enable/oam_start

Hi1102

On the Huawei P10 Lite, the order of the initialization should be the following (based on the *.rc files from Android):

# Install the files bfgx_and_wifi_cfg, wifi_cfg, bfgx_cfg, cr4_asic.bin, CPU_RAM_SCHED.bin, CPU_RAM_WBS.bin into /vendor/firmware/ (path could be
# patched in the kernel sources) and make sure the wifi and platform drivers are set as builtin, not modules (Y instead of M in kernel config)
echo 1 > /sys/hisys/boot/plat
echo 1 > /sys/hisys/boot/wifi
# The above commands can be run automatically on boot by installing hisi-wlan package

Debugging

First check, if the network interface is available by running ip link (wlan0 on most phones).

If the network interface is not listed and you've followed the section for your WiFi chip above, it's most likely an error of missing or misplaced firmware files:

  • dmesg
  • tail /var/log/firmwareload.log

If no issue pops up in the log files, it could also be that you are missing a configuration option in kernel config. For example: in the Sony Xperia Z downstream kernel we needed to enable these config options to get WiFi working:

 #
 # Qualcomm Atheros Prima WLAN module
 #
-# CONFIG_PRIMA_WLAN is not set
+CONFIG_PRIMA_WLAN=y
+# CONFIG_PRIMA_WLAN_BTAMP is not set
+CONFIG_PRIMA_WLAN_LFR=y
+CONFIG_PRIMA_WLAN_OKC=y
+# CONFIG_PRIMA_WLAN_11AC_HIGH_TP is not set
+# CONFIG_QCOM_VOWIFI_11R is not set
+CONFIG_QCOM_TDLS=y

In case you need any more help, just ask in our Matrix/IRC channel!

Connecting to APs

Using NetworkManager

You can use NetworkManager from the command line either with nmtui (a terminal user interface) or nmcli.

To use nmtui, just run sudo nmtui in your terminal.

To use nmcli, you can use the following commands, modified for your use case:

$ sudo nmcli device wifi list ifname wlan0
$ sudo nmcli device wifi connect "$SSID" password "$PASSWORD" ifname "wlan0"

See also: https://wiki.postmarketos.org/wiki/NetworkManager/DHCP

Using wpa_supplicant

Note In most cases using NetworkManager is preferred! You might need to set your wlan interface to unmanaged in NetworkManager or stop NetworkManager to configure it manually.

postmarketOS currently configures the wpa_supplicant service to start on boot. This service will fail to start unless /etc/wpa_supplicant/wpa_supplicant.conf has been defined. This can be configured using the wpa_passphrase utility:

$ wpa_passphrase YOUR_SSID YOUR_PASSPHRASE | sudo tee /etc/wpa_supplicant/wpa_supplicant.conf

Note: If you are connecting to a hidden wireless network, make sure to add line "scan_ssid=1" after the ssid line in your generated conf file

Scanning for networks is possible with these commands

ifconfig wlan0 up
iw dev wlan0 scan

Next you'll need to set up the networking service by adding interfaces to /etc/network/interfaces. In some cases, the loopback device may need to precede the wlan interface:

auto lo 
iface lo inet loopback 
auto wlan0 
iface wlan0 inet dhcp

Finally, set the networking service to start on boot:

$ sudo rc-update add networking default

Note that on some systems, you may have to configure wpa_supplicant to use the Linux kernel wireless extensions by editing /etc/conf.d/wpa_supplicant:

wpa_supplicant_args="-Dwext"

You will have to reboot, or manually restart the aforementioned services, before your device will connect to the access point.

Using wpa_supplicant (manually)

If you experience problems or just want to test wifi you can start wpa supplicant (using -Dwext or nl80211 driver) and the dhcp service:

sudo wpa_supplicant -u -Dnl80211 -B -c /etc/wpa_supplicant/wpa_supplicant.conf -iwlan0
sudo udhcpc -i wlan0

Troubleshooting

WiFi doesn't auto connect

If the WiFi does not auto connect after booting, there's likely a configuration issue in the network manager connection settings.

This can be fixed by editing /etc/NetworkManager/system-connections/<CONNECTION>.nmconnection and changing permissions=user:user:; to permissions=.
Alternatively, set 'Available to all users' in nmtui (nmtui might not work properly on your phone's screen, though).

see https://gitlab.com/postmarketOS/pmaports/-/issues/1049

Wifi Hotspot not connectable with Android

If you can not connect to a hotspot made with pmos, try it again after disabling pmf:

sudo nmcli connection modify Hotspot wifi-sec.pmf disable

See also