-
Notifications
You must be signed in to change notification settings - Fork 7
WiFi
Setting up WiFi on the Surface Pro X requires two parts: First, firmware and, second, user-space services.
Pre-built firmware packages are provided as linux-firmware-msft-surface-pro-x and linux-firmware-msft-surface-pro-x-qcom in our Arch Linux AArch64 Package Repository.
Those contain all the necessary firmware for WiFi.
Alternatively, most firmware files can be obtained from Windows. We provide a script to automatically gather and patch firmware files in https://github.com/linux-surface/aarch64-firmware. The inner workings of this script are explained in the respective subsections below in more detail, in case you prefer to follow these steps manually. In essence, you need to
- Obtain base firmware files from Windows.
- Create the
board-2.binfile. - Patch/edit the
firmware-5.binfile. - Move them to their respective directory.
The script does all that for you, meaning you only have to copy/install the firmware files to /lib/firmware.
For Arch Linux, we provide a package to replace the standard firmware at https://github.com/linux-surface/aarch64-packages.
The required user-space services are:
- Qualcomm IPC Router (
qrtr) - Protected Domain Mapper (
pd-mapper) - TFTP Server for Qualcom IPC (
tqftpserv) - Remote File System Service (
rmtfs)
For Arch Linux, packages are available in the AUR (using these names) or at https://github.com/linux-surface/aarch64-packages.
Note that due to a currently missing driver (issue #2), you will need to edit the rmtfs.service file, pointing it to dummy files instead of the (currently inaccessible) EFS partitions.
We again provide a package (rmtfs-dummy) for Arch Linux at https://github.com/linux-surface/aarch64-packages that replaces the standard rmtfs package.
Refer to the respective sections below for more details.
Once set up and installed, services can be started via
systemctl start pd-mapper
systemctl start tqftpserv
systemctl start rmtfsA tree of all firmware files required for WiFi is shown below:
/lib/firmware
├── ath10k
│ └── WCN3990
│ └── hw1.0
│ ├── board-2.bin
│ └── firmware-5.bin
└── qcom
└── msft
└── surface
└── pro-x-sq2
├── adspr.jsn
├── adspua.jsn
├── cdspr.jsn
├── charger.jsn
├── modemr.jsn
├── modemuw.jsn
├── qcmpss8180.mbn
├── qcmpss8180_nm.mbn
└── wlanmdsp.mbn
- You can obtain the
.mbnfiles from Windows. Both a live installation or a recovery image from https://support.microsoft.com/en-us/surface-recovery-image can be used. In particular, you want to search inC:\Windows\System32\DriverStore\FileRepository. These files are firmware for the modem/WiFi remote processor (i.e. program code). -
.jsnfiles can be found at https://github.com/linux-surface/aarch64-firmware/tree/main/firmware/qcom/msft/surface/pro-x-sq2. These json files are protected domain maps, required for thepd-mapperservice, which in turn is queried by the remote processors. - In addition, you will need
bdwlan.binandbdwlan.bNN/bdwlanu.bNNwhereNNstands for hex characters. These are required to create theboard-2.binfile as described below, which contains firmware (data/definitions?) for the WiFi module. - Lastly, you can obtain the
firmware-5.binfile from the official Linux firmware repository (i.e. here). This file contains feature flags for the WiFi driver.
The board-2.bin file is created from the bdf files (i.e. bdwlan.bin/bdwlan.bNN/bdwlanu.bNN) using https://github.com/qca/qca-swiss-army-knife, specifically the ath10k-bdencoder tool.
This tool can create a combined board-2.bin file from individual bdf files.
To create the board-2.bin file, first create a json file associating a bdf file with the snoc bus, board ID ff, and chip ID 30224.
For example:
[
{
"data": "path/to/bdwlan.b58",
"names": ["bus=snoc,qmi-board-id=ff,qmi-chip-id=30224"],
}
]Note that you need to adapt the path to point to your respective board file.
It is currently unknown which board file works best or is the intended file for this chip ID.
Any board file except for the .b5f ones seems to work.
Lastly run
./tools/scripts/ath10k/ath10k-bdencoder -c path/to/above.json -o board-2.binto create the final board-2.bin file.
The firmware running on the WiFi seems to send single events per channel instead of event pairs.
We therefore need to set the single-chan-info-per-channel flag in the firmware-5.bin file, or otherwise the ath10k driver will (somewhat cryptically) complain about receiving only a single event.
To do this, we again use https://github.com/qca/qca-swiss-army-knife via:
./tools/scripts/ath10k/ath10k-fwencoder --modify --features=wowlan,mgmt-tx-by-ref,non-bmi,single-chan-info-per-channel firmware-5.bin
See https://www.spinics.net/lists/linux-wireless/msg178387.html for more information on this.
Once you have set up and installed the required firmware, you can install and start the user-space services.
Install the respective services via the either the AUR packages or make && make install.
Note again that you need to adapt the rmtfs.service as described in its section below (or use the rmtfs-dummy package).
Router for IPC communication between kernel and user-space processes and remote processors.
- Source: https://github.com/andersson/qrtr.git
- AUR package: https://aur.archlinux.org/packages/qrtr-git
Queried by remote processors for domain maps.
- Source: https://github.com/andersson/pd-mapper.git
- AUR package: https://aur.archlinux.org/packages/pd-mapper-git
TFTP server for giving remote processors access to firmware files.
- Source: https://github.com/andersson/tqftpserv.git
- AUR package: https://aur.archlinux.org/packages/tqftpserv-git
Service for giving remote processors access to EFS partitions.
- Source: https://github.com/andersson/rmtfs.git
- Patched package: https://github.com/linux-surface/aarch64-packages/tree/main/rmtfs-dummy
- AUR package: https://aur.archlinux.org/packages/rmtfs-git
We currently do not have access to the EFS partitions on the Surface Pro X (see issue #2).
Therefore the rmtfs service will fail to find those.
To alleviate this problem, we can re-direct access to ~2MB sized zero-filled dummy files, which seems to work as a temporary workaround.
To create these files, run
mkdir -p /var/lib/rmtfs
dd if=/dev/zero of="/var/lib/rmtfs/modem_fs1" bs=2M count=1
dd if=/dev/zero of="/var/lib/rmtfs/modem_fs2" bs=2M count=1
dd if=/dev/zero of="/var/lib/rmtfs/modem_fsc" bs=2M count=1
dd if=/dev/zero of="/var/lib/rmtfs/modem_fsg" bs=2M count=1
dd if=/dev/zero of="/var/lib/rmtfs/modem_tuning" bs=2M count=1Then edit the rmtfs.service, e.g. via systemctl edit rmtfs.service and replace the -P option with -o /var/lib/rmtfs, e.g. as shown here.
You can choose the path for the dummy files as you wish.
Note that the patched package provided at https://github.com/linux-surface/aarch64-packages/blob/main/rmtfs-dummy does all of this for you.