Getting my new laptop to work

May 03, 2018 posted by Maya Rashish

I've recently been gifted a fancy laptop - a Dell XPS 15 9550.
I want to run NetBSD on it and have it run well, and I've set aside time to achieve this.
Things work surprisingly well out of the box - touchscreen and touchpad work, but need to be calibrated better. 4K video is displayed, but without graphical acceleration, which is somewhat slow. I could adjust the resolution to be lower, but haven't tried yet.

These are some of the lessons I learned from doing this, being new to drivers and networking.

rtsx - SD card reader

This one was simple and straightforward.
The PCI ID of my SD is 10ec:525a, a realtek PCI device with ID 0x525a.
Normal SD card readers are supported by a generic driver, but mine wasn't.
I've been told that when SD cards don't present themselves as the generic device, it is for good reason.

Adding the PCI device ID to sys/dev/pci/pcidevs would have revealed the adjacent entries:

product REALTEK RTS5229		0x5229	RTS5229 PCI-E Card Reader
product REALTEK RTS5249		0x5249	RTS5249 PCI-E Card Reader
product REALTEK RTS525A		0x525A	RTS525A PCI-E Card Reader <- my addition
product REALTEK RTL8402		0x5286	RTL8402 PCI-E Card Reader

These are all supported by rtsx(4), which is a driver originally from OpenBSD.
Looking at the driver in OpenBSD, it has diverged since, and indeed someone had added RTS525A support.

I've initially tried to synchronize the driver, but it seemed beyond my capabilities, and just went to steal the support.
Found the individual commit and it was kinda ugly, there are conditionals for variants in some functions.
I've added the RTS525A in the matching conditionals.

It would have been nice to make it less ugly, but I'm only adding a bit of fuel to the fire.
I've received hints that drivers for hardware from some manufacturers is going to be ugly either way.

I saw that "read-only detect" is not supported. Curious if I could added, I wondered what happens if you try to write when the SD card's read-only switch is held. Apparently this is a suggestion for software, I could read back the contents I wrote after detach. perhaps not having the support isn't too bad.

bwfm - wireless networking

Previously, Broadcom wifi in a laptop would have resulted in sadness, followed by disassembly and hopeful replacement, unless the manufacturer has chosen to whitelist wireless cards, in which case I am doomed to a USB wifi card.
Thanks to bluerise@openbsd, jmcneill and Broadcom for open sourcing their drivers, we now have a port of the linux brcmfmac driver, for Broadcom FullMAC wireless devices. Mine is one.

These devices do a lot of 802.11 weight lifting on their own. Unfortunately that means that if they hadn't had their firmware updated, vulnerabilities are likely, such as KRACK. Previously jmcneill had made it work for the USB variant, and even made it use some of the kernel's 802.11 code, allowing to avoid some vulnerabilities.

He did not port the PCI variant, added later in OpenBSD. I've set out to steal this code.

First and foremost, I need the ability to express 'please build the pci variant code', or to add it to the pci config.
The files I have for the driver are:

sys/dev/ic/{bwfm.c, bwfmvar.h, bwfmreg.h}
The USB variant already exists, it uses:
sys/dev/ic/{bwfm.c, bwfmvar.h, bwfmreg.h}
ic is something shared among pci, usb, sdio code. the code for it is already built due to being added to sys/conf/files.
I only need to add the PCI code.

The file for this is sys/dev/pci/files.pci. Fortunately it has plenty of examples, and here is what I added:

# Broadcom FullMAC USB wireless adapter
attach	bwfm at pci with bwfm_pci: firmload
file	dev/pci/if_bwfm_pci.c		bwfm_pci

I've had to adapt APIs - some OpenBSD ones not existing in NetBSD. Fortunately there are lots of drivers to look around. I've made a very simple if_rxr_* and made it static. MCLGETI I copied from another driver, again static.
My first attempt at if_rxr_* (however simple) didn't seem to work. I rewrote it and made sure to KASSERT assumptions I assume are correct.
I was hoping to find an existing "NetBSD-ish" API for this, but I'm not sure there is something quite like it, and it is pretty simple. But it was a good opportunity to learn more about NetBSD APIs.

Once I got it to compile and not panic on attach, I had a problem. sending a message to the device failed to get the appropriate response, and attach failed.
I've spent a long time reading the initialization sequence, in OpenBSD and in linux brcmfmac, but couldn't find anything. I was ready to give up, but then I decided to diff my file to OpenBSD, and saw that in an attempt to calm type warnings (fatal by default, as NetBSD builds with -Werror), I made some unnecessary and incorrect changes.
I've switched to building without -Werror (that means passing -V NOGCCERROR=1 to, or adding to mk.conf) and reverted this changes, and then it attached cleanly.
In retrospect, I shouldn't have made unnecessary changes as a beginner. -V NOGCCERROR=1 is there. Device work first, cosmetic warning fixes second.

After it had attached, I tried to connect. I hoped wpa_supplicant -d would tell why it failed, but it only said that the connection times out.
Like many drivers in the *BSD world, bwfm has a BWFM_DEBUG and a debug printf that is controllable. I turned it on to get these messages from bwfm_rx_event:

bwfm0: newstate 0 -> 1
bwfm0: newstate 1 -> 1
bwfm_rx_event: buf 0xffffe404b97f9010 len 354 datalen 280 code 69 status 8 reason 0
bwfm_rx_event: buf 0xffffe404b97f9010 len 354 datalen 280 code 69 status 8 reason 0
bwfm_rx_event: buf 0xffffe404b97f9010 len 362 datalen 288 code 69 status 8 reason 0
bwfm_rx_event: buf 0xffffe404b97f9010 len 354 datalen 280 code 69 status 8 reason 0
bwfm_rx_event: buf 0xffffe404b97f9010 len 354 datalen 280 code 69 status 8 reason 0
bwfm_rx_event: buf 0xffffe404b97f9010 len 354 datalen 280 code 69 status 8 reason 0
bwfm_rx_event: buf 0xffffe404b97f9010 len 362 datalen 288 code 69 status 8 reason 0
bwfm_rx_event: buf 0xffffe404b97f9010 len 354 datalen 280 code 69 status 8 reason 0
bwfm_rx_event: buf 0xffffe404b97f9010 len 86 datalen 12 code 69 status 0 reason 0
bwfm_rx_event: buf 0xffffe404b9837010 len 74 datalen 0 code 26 status 0 reason 0
bwfm0: newstate 1 -> 2
bwfm_rx_event: buf 0xffffe404b9837010 len 82 datalen 8 code 0 status 3 reason 0
bwfm0: newstate 2 -> 1

To decipher the messages, I picked up what the various numbers means. Deciphered, it says:

802.11 state INIT -> SCAN
802.11 state SCAN -> SCAN
received messages from the driver:
code 69 (scan result)
code 26 (scan end)
802.11 state SCAN -> AUTH
code 0 (SET_SSID) status 3 (NO NETWORKS)
802.11 state AUTH -> SCAN

Authenticating is failing to find a matching network. But why?
Now experienced with the previous experience ("I've found my problem! it was me!"), I went back to some more attempts to sync the driver, which changed the SSID-setting code.

With this corrected, the driver worked as expected.

In total, it would have been easier to start with a working driver and adapting it to make some changes, like having the USB variant or testing on OpenBSD, but I managed anyway, it just took longer.
In two weeks I will receive the USB variant, but the driver is already working for me. I had trouble installing OpenBSD on the same machine.

I'll clean up my changes and post it for review soon.

Thanks to jak, pgoyette, rkujawa, phone for various fixes.
Thanks to maxv for fixing a bug affecting my use of a network stack API.
Thanks to bluerise@openbsd and jmcneill for the prior driver work.
Thanks to Broadcom for providing open source drivers under a friendly license.

remaining work - graphical acceleration.

NetBSD's x86 graphical acceleration is mostly from Linux, from linux 3.15.
This predates support for my Skylake GPU and nVidia graphics on my machine, and also the ability to dual-GPU effectively.
I'll try to sync the drivers and made previous attempts to learn about graphics, but I can't promise anything.



Post a Comment:
Comments are closed for this entry.